JS實(shí)現(xiàn)圖片懶加載(lazyload)過(guò)程詳解
對(duì)于圖片較多的頁(yè)面,使用懶加載可以大幅提高頁(yè)面加載速度,提高用戶體驗(yàn)。
懶加載的意義(為什么要使用懶加載)
對(duì)頁(yè)面加載速度影響最大的就是圖片,一張普通的圖片可以達(dá)到幾M的大小,而代碼也許就只有幾十KB。當(dāng)頁(yè)面圖片很多時(shí),頁(yè)面的加載速度緩慢,幾S鐘內(nèi)頁(yè)面沒(méi)有加載完成,也許會(huì)失去很多的用戶。
所以,對(duì)于圖片過(guò)多的頁(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='http://m.lshqa.cn/bcjs/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)聽(tīng)滾動(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='http://m.lshqa.cn/bcjs/default.jpg' data-src='http://ww4.sinaimg.cn/large/006y8mN6gw1fa5obmqrmvj305k05k3yh.jpg' alt=''> <img src='http://m.lshqa.cn/bcjs/default.jpg' data-src='http://ww4.sinaimg.cn/large/006y8mN6gw1fa5obmqrmvj305k05k3yh.jpg' alt=''> <img src='http://m.lshqa.cn/bcjs/default.jpg' data-src='http://ww1.sinaimg.cn/large/006y8mN6gw1fa7kaed2hpj30sg0l9q54.jpg' alt=''> <img src='http://m.lshqa.cn/bcjs/default.jpg' data-src='http://ww1.sinaimg.cn/large/006y8mN6gw1fa7kaed2hpj30sg0l9q54.jpg' alt=''> <img src='http://m.lshqa.cn/bcjs/default.jpg' data-src='http://ww4.sinaimg.cn/large/006y8mN6gw1fa5obmqrmvj305k05k3yh.jpg' alt=''> <img src='http://m.lshqa.cn/bcjs/default.jpg' data-src='http://ww4.sinaimg.cn/large/006y8mN6gw1fa5obmqrmvj305k05k3yh.jpg' alt=''> <img src='http://m.lshqa.cn/bcjs/default.jpg' data-src='http://ww4.sinaimg.cn/large/006y8mN6gw1fa5obmqrmvj305k05k3yh.jpg' alt=''> <img src='http://m.lshqa.cn/bcjs/default.jpg' data-src='http://ww4.sinaimg.cn/large/006y8mN6gw1fa5obmqrmvj305k05k3yh.jpg' alt=''> <img src='http://m.lshqa.cn/bcjs/default.jpg' data-src='http://ww1.sinaimg.cn/large/006y8mN6gw1fa7kaed2hpj30sg0l9q54.jpg' alt=''> <img src='http://m.lshqa.cn/bcjs/default.jpg' data-src='http://ww4.sinaimg.cn/large/006y8mN6gw1fa5obmqrmvj305k05k3yh.jpg' alt=''> <img src='http://m.lshqa.cn/bcjs/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ǔ)圖片加載到的位置,避免每次都從第一張圖片開(kāi)始遍歷 lazyload(); //頁(yè)面載入完畢加載可是區(qū)域內(nèi)的圖片 window.onscroll = lazyload; function lazyload() { //監(jiān)聽(tīng)頁(yè)面滾動(dòng)事件 var seeHeight = document.documentElement.clientHeight; //可見(jiàn)區(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 { // 沒(méi)達(dá)到觸發(fā)間隔,重新設(shè)定定時(shí)器 timeout = setTimeout(function () { fun.apply(context, args) }, delay) } }};// 實(shí)際想綁定在 scroll 事件上的 handlerfunction 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í)有所幫助,也希望大家多多支持好吧啦網(wǎng)。
相關(guān)文章:
