Javascript實(shí)現(xiàn)圖片懶加載的示例代碼
未做優(yōu)化實(shí)例
以下代碼僅作為示例演示給大家看,不是公司內(nèi)部代碼。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <img src="https://img.36krcdn.com/20190808/v2_1565254363234_img_jpg"> <img src="https://img.36krcdn.com/20190905/v2_1567641293753_img_png"> <img src="https://img.36krcdn.com/20190905/v2_1567640518658_img_png"> <img src="https://img.36krcdn.com/20190905/v2_1567642423719_img_000"> <img src="https://img.36krcdn.com/20190905/v2_1567642425030_img_000"> <img src="https://img.36krcdn.com/20190905/v2_1567642425101_img_000"> <img src="https://img.36krcdn.com/20190905/v2_1567642425061_img_000"> <img src="https://img.36krcdn.com/20190904/v2_1567591358070_img_jpg"> <img src="https://img.36krcdn.com/20190905/v2_1567641974410_img_000"> <img src="https://img.36krcdn.com/20190905/v2_1567641974454_img_000"> </body> </html>
一次性加載所有的圖片,這對(duì)瀏覽器的頁面加載是不友好的。
瀏覽器的工作機(jī)制
1.首先了解一下瀏覽器的運(yùn)行機(jī)制
當(dāng)我們?cè)L問一個(gè)網(wǎng)頁時(shí)
- 解析HTML文檔:瀏覽器從服務(wù)器獲取HTML文檔并開始解析,構(gòu)建DOM樹。
- 下載樣式表:瀏覽器下載CSS樣式表,并形成CSS樹。
- 渲染頁面:瀏覽器將DOM樹和CSS樹結(jié)合起來,生成渲染樹,并最終繪制出可見的頁面。
- 處理腳本:如果頁面中有JavaScript腳本,瀏覽器會(huì)執(zhí)行這些腳本。
2.雖然 JS 是單線程的,但是瀏覽器是多線程的;img
標(biāo)簽和 script
標(biāo)簽一樣都會(huì)讓瀏覽器啟動(dòng)新的下載線程去下載圖片、JS 文件等;如果頁面上同時(shí)讓很多圖片一起加載,那會(huì)讓瀏覽器啟動(dòng)很多并發(fā)任務(wù),增加瀏覽器的壓力;這就猶如上高速,車流量如果太大,就容易造成堵塞。
懶加載
要實(shí)現(xiàn)懶加載,我們需要手動(dòng)控制圖片的加載過程,而不是讓瀏覽器自動(dòng)下載所有的<img>
標(biāo)簽中的圖片。
1.使用數(shù)據(jù)屬性
將實(shí)際的圖片地址存儲(chǔ)在data-src
屬性中
<img data-src="https://img.36krcdn.com/20190905/v2_1567641293753_img_png"> <img data-src="https://img.36krcdn.com/20190905/v2_1567640518658_img_png">
2.監(jiān)聽滾動(dòng)事件
// 當(dāng)DOM內(nèi)容加載完成后執(zhí)行 document.addEventListener('scroll', () => { // 調(diào)用loadImage函數(shù) loadImage(); });
3.功能函數(shù)的實(shí)現(xiàn)
// 定義 loadImage 函數(shù) function loadImage() { // 獲取文檔的可視區(qū)高度 let screenHeight = document.documentElement.clientHeight; // 獲取滾動(dòng)條的位置(兼容不同瀏覽器) let scrollTop = document.documentElement.scrollTop || document.body.scrollTop; // 遍歷所有圖片 for(let i = 0; i < num; i++){ // 檢查當(dāng)前圖片是否在可視區(qū)內(nèi) if(imgs[i].offsetTop<screenHeight + scrollTop){ // 獲取圖片的 src 屬性值(使用 data 屬性) imgs[i].src = imgs[i].getAttribute('data-src'); // 更新當(dāng)前加載的圖片索引 n = i + 1; // 檢查是否加載完所有需要懶加載的圖片 if (n === num){ // 停止監(jiān)聽滾動(dòng)事件,進(jìn)行性能優(yōu)化 window.removeEventListener('scroll', loadImage); } } } }
clientHeight
用于獲取元素的可見高度(不包括邊框、內(nèi)邊距和外邊距)。此屬性通常用于獲取諸如窗口、文檔或元素的高度scrollTop
用于獲取或設(shè)置一個(gè)元素相對(duì)于其滾動(dòng)容器的垂直滾動(dòng)距離。這個(gè)值是從元素頂部到視口頂部的距離offsetTop
用于獲取元素相對(duì)于最近的帶有定位(positioned)祖先元素的頂部偏移量。如果沒有定位的祖先,則相對(duì)于文檔的頂部
優(yōu)化:懶加載進(jìn)行防抖
由于滾動(dòng)事件太敏感,容易高頻觸發(fā)懶加載函數(shù)loadImage
,我們可以給它添加一個(gè)防抖的優(yōu)化操作,減少事件的觸發(fā)。
工具庫
<script src="https://cdn.bootcdn.net/ajax/libs/lodash.js/4.17.21/lodash.min.js"></script>
完整代碼
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <script src="https://cdn.bootcdn.net/ajax/libs/lodash.js/4.17.21/lodash.min.js"></script> </head> <body> <img data-price="20" data-src="https://img.36krcdn.com/20190808/v2_1565254363234_img_jpg"> <img data-src="https://img.36krcdn.com/20190905/v2_1567641293753_img_png"> <img data-src="https://img.36krcdn.com/20190905/v2_1567640518658_img_png"> <img data-src="https://img.36krcdn.com/20190905/v2_1567642423719_img_000"> <img data-src="https://img.36krcdn.com/20190905/v2_1567642425030_img_000"> <img data-src="https://img.36krcdn.com/20190905/v2_1567642425101_img_000"> <img data-src="https://img.36krcdn.com/20190905/v2_1567642425061_img_000"> <img data-src="https://img.36krcdn.com/20190904/v2_1567591358070_img_jpg"> <img data-src="https://img.36krcdn.com/20190905/v2_1567641974410_img_000"> <img data-src="https://img.36krcdn.com/20190905/v2_1567641974454_img_000"> <script> // 獲取頁面中所有的img元素 const imgs = document.getElementsByTagName('img'); // 獲取img元素的數(shù)量 const num = imgs.length; // 記錄當(dāng)前加載的是第幾張圖片,從0開始 let n = 0; // 當(dāng)DOM完全加載后,執(zhí)行l(wèi)oadImage函數(shù) document.addEventListener('DOMContentLoaded', () => { loadImage(); }); // 定義loadImage函數(shù) function loadImage() { console.log('121122'); // 獲取可視區(qū)域的高度,兼容不同瀏覽器 let screenHeight = document.documentElement.clientHeight; // 獲取滾動(dòng)條的位置,兼容不同瀏覽器 let scrollTop = document.documentElement.scrollTop || document.body.scrollTop; // 遍歷所有圖片 for (let i = 0; i < num; i++){ // 如果圖片的頂部位置在可視區(qū)內(nèi) if (imgs[i].offsetTop < screenHeight + scrollTop){ // 設(shè)置圖片的src屬性 imgs[i].src = imgs[i].getAttribute('data-src'); // 更新加載的圖片索引 n = i + 1; // 如果所有圖片都已加載,則移除scroll事件的監(jiān)聽器,進(jìn)行性能優(yōu)化 if (n === num){ // console.log('加載完成'); // 所有圖片加載完成后,移除功能函數(shù) window.removeEventListener('scroll', throttleLazyLoad); } } } } // 使用Lodash的throttle函數(shù)來延遲loadImage的執(zhí)行,減少性能開銷 const throttleLazyLoad = _.throttle(loadImage, 300); // 添加scroll事件監(jiān)聽器,在滾動(dòng)時(shí)執(zhí)行throttleLazyLoad window.addEventListener('scroll', throttleLazyLoad); </script> </body> </html>
總結(jié)
圖片懶加載是一項(xiàng)簡(jiǎn)單而有效的前端性能優(yōu)化技術(shù),歡迎大家一起討論其他更好的方法。
到此這篇關(guān)于Javascript實(shí)現(xiàn)圖片懶加載的示例代碼的文章就介紹到這了,更多相關(guān)Javascript圖片懶加載內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
layui 實(shí)現(xiàn)table翻頁滾動(dòng)條位置保持不變的例子
今天小編就為大家分享一篇layui 實(shí)現(xiàn)table翻頁滾動(dòng)條位置保持不變的例子,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2019-09-09用js閉包的方法實(shí)現(xiàn)多點(diǎn)標(biāo)注冒泡示例
這篇文章主要介紹了用js閉包的方法實(shí)現(xiàn)多點(diǎn)標(biāo)注冒泡,需要的朋友可以參考下2014-05-05利用JS響應(yīng)式修改vue實(shí)現(xiàn)頁面的input值
這篇文章主要給大家介紹了關(guān)于如何利用JS響應(yīng)式修改vue實(shí)現(xiàn)頁面的input值,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用JS具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2019-09-09javascript 獲取所有id中包含某關(guān)鍵字的控件的實(shí)現(xiàn)代碼
獲取某容器控件中id包含某字符串的控件id列表2010-11-11JS實(shí)現(xiàn)select選中option觸發(fā)事件操作示例
這篇文章主要介紹了JS實(shí)現(xiàn)select選中option觸發(fā)事件操作,結(jié)合實(shí)例形式總結(jié)分析了javascript針對(duì)select下拉選中option項(xiàng)觸發(fā)事件相關(guān)操作技巧,需要的朋友可以參考下2018-07-07基于JavaScript中字符串的match與replace方法(詳解)
下面小編就為大家介紹一下JavaScript中的字符串的match與replace方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2017-12-12javascript得到XML某節(jié)點(diǎn)的子節(jié)點(diǎn)個(gè)數(shù)的腳本
得到XML某節(jié)點(diǎn)(pnode)的子節(jié)點(diǎn)個(gè)數(shù)(客戶端)2008-10-10JS正則表達(dá)式修飾符中multiline(/m)用法分析
這篇文章主要介紹了JS正則表達(dá)式修飾符中multiline(/m)用法,結(jié)合實(shí)例形式分析了JS正則中多行模式multiline的功能、使用方法與相關(guān)注意事項(xiàng),需要的朋友可以參考下2016-12-12