JS實(shí)現(xiàn)圖片懶加載(lazyload)過程詳解
對(duì)于圖片較多的頁(yè)面,使用懶加載可以大幅提高頁(yè)面加載速度,提高用戶體驗(yàn)。
懶加載的意義(為什么要使用懶加載)
對(duì)頁(yè)面加載速度影響最大的就是圖片,一張普通的圖片可以達(dá)到幾M的大小,而代碼也許就只有幾十KB。當(dāng)頁(yè)面圖片很多時(shí),頁(yè)面的加載速度緩慢,幾S鐘內(nèi)頁(yè)面沒有加載完成,也許會(huì)失去很多的用戶。
所以,對(duì)于圖片過多的頁(yè)面,為了加速頁(yè)面加載速度,所以很多時(shí)候我們需要將頁(yè)面內(nèi)未出現(xiàn)在可視區(qū)域內(nèi)的圖片先不做加載, 等到滾動(dòng)到可視區(qū)域后再去加載。這樣子對(duì)于頁(yè)面加載性能上會(huì)有很大的提升,也提高了用戶體驗(yàn)。
原理
將頁(yè)面中的img標(biāo)簽src指向一張小圖片或者src為空,然后定義data-src(這個(gè)屬性可以自定義命名,我才用data-src)屬性指向真實(shí)的圖片。src指向一張默認(rèn)的圖片,否則當(dāng)src為空時(shí)也會(huì)向服務(wù)器發(fā)送一次請(qǐng)求。可以指向loading的地址。
注:圖片要指定寬高
<img src="default.jpg" data-src="http://ww4.sinaimg.cn/large/006y8mN6gw1fa5obmqrmvj305k05k3yh.jpg" />
當(dāng)載入頁(yè)面時(shí),先把可視區(qū)域內(nèi)的img標(biāo)簽的data-src屬性值負(fù)給src,然后監(jiān)聽滾動(dòng)事件,把用戶即將看到的圖片加載。這樣便實(shí)現(xiàn)了懶加載。
代碼
<head> <meta charset="UTF-8"> <title>Document</title> <style> img { display: block; margin-bottom: 50px; width: 400px; height: 400px; } </style> </head> <body> <img src="default.jpg" data-src="http://ww4.sinaimg.cn/large/006y8mN6gw1fa5obmqrmvj305k05k3yh.jpg" alt=""> <img src="default.jpg" data-src="http://ww4.sinaimg.cn/large/006y8mN6gw1fa5obmqrmvj305k05k3yh.jpg" alt=""> <img src="default.jpg" data-src="http://ww1.sinaimg.cn/large/006y8mN6gw1fa7kaed2hpj30sg0l9q54.jpg" alt=""> <img src="default.jpg" data-src="http://ww1.sinaimg.cn/large/006y8mN6gw1fa7kaed2hpj30sg0l9q54.jpg" alt=""> <img src="default.jpg" data-src="http://ww4.sinaimg.cn/large/006y8mN6gw1fa5obmqrmvj305k05k3yh.jpg" alt=""> <img src="default.jpg" data-src="http://ww4.sinaimg.cn/large/006y8mN6gw1fa5obmqrmvj305k05k3yh.jpg" alt=""> <img src="default.jpg" data-src="http://ww4.sinaimg.cn/large/006y8mN6gw1fa5obmqrmvj305k05k3yh.jpg" alt=""> <img src="default.jpg" data-src="http://ww4.sinaimg.cn/large/006y8mN6gw1fa5obmqrmvj305k05k3yh.jpg" alt=""> <img src="default.jpg" data-src="http://ww1.sinaimg.cn/large/006y8mN6gw1fa7kaed2hpj30sg0l9q54.jpg" alt=""> <img src="default.jpg" data-src="http://ww4.sinaimg.cn/large/006y8mN6gw1fa5obmqrmvj305k05k3yh.jpg" alt=""> <img src="default.jpg" data-src="http://ww4.sinaimg.cn/large/006y8mN6gw1fa5obmqrmvj305k05k3yh.jpg" alt=""> </body>
JavaScript
<script> var num = document.getElementsByTagName('img').length; var img = document.getElementsByTagName("img"); var n = 0; //存儲(chǔ)圖片加載到的位置,避免每次都從第一張圖片開始遍歷 lazyload(); //頁(yè)面載入完畢加載可是區(qū)域內(nèi)的圖片 window.onscroll = lazyload; function lazyload() { //監(jiān)聽頁(yè)面滾動(dòng)事件 var seeHeight = document.documentElement.clientHeight; //可見區(qū)域高度 var scrollTop = document.documentElement.scrollTop || document.body.scrollTop; //滾動(dòng)條距離頂部高度 for (var i = n; i < num; i++) { if (img[i].offsetTop < seeHeight + scrollTop) { if (img[i].getAttribute("src") == "default.jpg") { img[i].src = img[i].getAttribute("data-src"); } n = i + 1; } } } </script>
jQuery
<script> var n = 0, imgNum = $("img").length, img = $('img'); lazyload(); $(window).scroll(lazyload); function lazyload(event) { for (var i = n; i < imgNum; i++) { if (img.eq(i).offset().top < parseInt($(window).height()) + parseInt($(window).scrollTop())) { if (img.eq(i).attr("src") == "default.jpg") { var src = img.eq(i).attr("data-src"); img.eq(i).attr("src", src); n = i + 1; } } } } </script>
使用節(jié)流函數(shù)進(jìn)行性能優(yōu)化
如果直接將函數(shù)綁定在scroll事件上,當(dāng)頁(yè)面滾動(dòng)時(shí),函數(shù)會(huì)被高頻觸發(fā),這非常影響瀏覽器的性能。
我想實(shí)現(xiàn)限制觸發(fā)頻率,來(lái)優(yōu)化性能。
節(jié)流函數(shù):只允許一個(gè)函數(shù)在N秒內(nèi)執(zhí)行一次。下面是一個(gè)簡(jiǎn)單的節(jié)流函數(shù):
// 簡(jiǎn)單的節(jié)流函數(shù) //fun 要執(zhí)行的函數(shù) //delay 延遲 //time 在time時(shí)間內(nèi)必須執(zhí)行一次 function throttle (fun, delay, time) { let timeout let startTime = new Date() return function () { let context = this let args = Array.prototype.slice.call(arguments) let curTime = new Date() clearTimeout(timeout) if (curTime - startTime >= time) { // 如果達(dá)到了規(guī)定的觸發(fā)時(shí)間間隔,觸發(fā) handler fun.apply(context, args) startTime = curTime } else { // 沒達(dá)到觸發(fā)間隔,重新設(shè)定定時(shí)器 timeout = setTimeout(function () { fun.apply(context, args) }, delay) } } }; // 實(shí)際想綁定在 scroll 事件上的 handler function lazyload(event) {} // 采用了節(jié)流函數(shù) window.addEventListener('scroll',throttle(lazyload,500,1000));
使用去抖函數(shù)進(jìn)行性能優(yōu)化
去抖相比較節(jié)流函數(shù)要稍微簡(jiǎn)單一點(diǎn),去抖是讓函數(shù)延遲執(zhí)行,而節(jié)流比去抖多了一個(gè)在一定時(shí)間內(nèi)必須要執(zhí)行一次。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
JavaScript模運(yùn)算符理解及運(yùn)用實(shí)戰(zhàn)
這篇博客文章是為初級(jí)到中級(jí)JavaScript開發(fā)人員所寫,主要為大家介紹了JavaScript模運(yùn)算符理解及運(yùn)用實(shí)戰(zhàn)示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步2023-11-11JavaScript中prompt()函數(shù)的用法實(shí)戰(zhàn)例子
JavaScript中的prompt是一個(gè)函數(shù),用于在瀏覽器中顯示一個(gè)對(duì)話框,提示用戶輸入一些信息,這篇文章主要給大家介紹了關(guān)于JavaScript中prompt()函數(shù)的用法實(shí)戰(zhàn),需要的朋友可以參考下2023-11-11微信小程序頁(yè)面跳轉(zhuǎn)功能之從列表的item項(xiàng)跳轉(zhuǎn)到下一個(gè)頁(yè)面的方法
這篇文章主要介紹了微信小程序頁(yè)面跳轉(zhuǎn)功能之從列表的item項(xiàng)跳轉(zhuǎn)到下一個(gè)頁(yè)面的方法,結(jié)合具體實(shí)例形式總結(jié)分析了微信小程序頁(yè)面跳轉(zhuǎn)及列表item項(xiàng)跳轉(zhuǎn)頁(yè)面的相關(guān)操作技巧,需要的朋友可以參考下2017-11-11前端實(shí)現(xiàn)批量下載并打包成ZIP文件的步驟及示例
下載我相信很多小伙伴并不陌生,下載文件的形式也有很多,下面這篇文章主要給大家介紹了關(guān)于前端實(shí)現(xiàn)批量下載并打包成ZIP文件的步驟及示例,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下2024-07-07有關(guān)div頁(yè)面拖動(dòng)、縮放、關(guān)閉、遮罩效果代碼
有關(guān)div頁(yè)面拖動(dòng)、縮放、關(guān)閉、遮罩效果代碼,比較不錯(cuò),適合學(xué)習(xí)用。2009-08-08Actionscript與javascript交互實(shí)例程序(修改)
這篇文章主要介紹了Actionscript與javascript交互實(shí)例程序(修改)的相關(guān)資料,本文介紹的非常詳細(xì),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-09-09