原生JS實現(xiàn)圖片懶加載之頁面性能優(yōu)化
在項目開發(fā)中,我們往往會遇到一個頁面需要加載很多圖片的情況。我們可以一次性加載全部的圖片,但是考慮到用戶有可能只瀏覽部分圖片。所以我們需要對圖片加載進行優(yōu)化,只加載瀏覽器窗口內(nèi)的圖片,當(dāng)用戶滾動時,再加載更多的圖片。這種加載圖片的方式叫做圖片懶加載,又叫做按需加載或圖片的延時加載。這樣做的好處是:1.可以加快頁面首屏渲染的速度;2.節(jié)約用戶的流量。
一.實現(xiàn)思路
1.圖片img標簽自定義一個屬性data-src來存放真實的地址。
2.當(dāng)滾動頁面時,檢查所有的img標簽,判斷是否出現(xiàn)在事業(yè)中,如果出現(xiàn)在視野中,繼續(xù)進行判斷,看齊是否被加載過了,如果沒有加載,那就進行加載。
判斷圖片元素是否處于瀏覽器視野中的示意圖(手繪):

二.根據(jù)思路完成代碼如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>原生js實現(xiàn)圖片懶加載</title>
<style>
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}
ul{
overflow: hidden;
list-style: none;
}
li{
float: left;
width: 50%;
height: 200px;
padding: 10px;
}
li img{
display: inline-block;
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<div class="container">
<ul>
<li><img src="http://cdn.jirengu.com/book.jirengu.com/img/1.jpg" alt="" data-src="http://cdn.jirengu.com/book.jirengu.com/img/1.jpg"></li>
<li><img src="" alt="" data-src="http://cdn.jirengu.com/book.jirengu.com/img/2.jpg"></li>
<li><img src="" alt="" data-src="http://cdn.jirengu.com/book.jirengu.com/img/3.jpg"></li>
<li><img src="" alt="" data-src="http://cdn.jirengu.com/book.jirengu.com/img/4.jpg"></li>
<li><img src="" alt="" data-src="http://cdn.jirengu.com/book.jirengu.com/img/5.jpg"></li>
<li><img src="" alt="" data-src="http://cdn.jirengu.com/book.jirengu.com/img/6.jpg"></li>
<li><img src="" alt="" data-src="http://cdn.jirengu.com/book.jirengu.com/img/7.jpg"></li>
<li><img src="" alt="" data-src="http://cdn.jirengu.com/book.jirengu.com/img/8.jpg"></li>
<li><img src="" alt="" data-src="http://cdn.jirengu.com/book.jirengu.com/img/9.jpg"></li>
<li><img src="" alt="" data-src="http://cdn.jirengu.com/book.jirengu.com/img/10.jpg"></li>
<li><img src="" alt="" data-src="http://cdn.jirengu.com/book.jirengu.com/img/11.jpg"></li>
<li><img src="" alt="" data-src="http://cdn.jirengu.com/book.jirengu.com/img/12.jpg"></li>
<li><img src="" alt="" data-src="http://cdn.jirengu.com/book.jirengu.com/img/13.jpg"></li>
<li><img src="" alt="" data-src="http://cdn.jirengu.com/book.jirengu.com/img/14.jpg"></li>
<li><img src="" alt="" data-src="http://cdn.jirengu.com/book.jirengu.com/img/15.jpg"></li>
<li><img src="" alt="" data-src="http://cdn.jirengu.com/book.jirengu.com/img/16.jpg"></li>
</ul>
</div>
<script>
// window綁定滾動事件
window.addEventListener('scroll',function(){
// 遍歷所有的img標簽
Array.prototype.slice.apply(document.getElementsByTagName('li')).forEach((li)=>{
let img=li.getElementsByTagName('img')[0];
// 判斷當(dāng)前img是否出現(xiàn)在了視野中
// 判斷當(dāng)前img是否被加載過了
if(checkShow(img) && !isLoaded(img)){
loadImg(img);
}
})
});
// 判斷img是否出現(xiàn)瀏覽器視野中
function checkShow(img) {
let scrollTop=document.documentElement.scrollTop; // 頁面向上滾動的高度
let windowHeight=window.innerHeight; //瀏覽器自身高度
let offsetTop=img.offsetTop; //目標標簽相對于document的高度
return (offsetTop > scrollTop && offsetTop <(windowHeight + scrollTop));
}
// 判斷是否已經(jīng)加載過
function isLoaded(img) {
return img.getAttribute('src')===img.getAttribute('data-src');
}
// 加載圖片
function loadImg(img) {
img.setAttribute('src',img.getAttribute('data-src'));
}
</script>
</body>
</html>
好了,在瀏覽器中運行一下,第一次進頁面如果不滾動滾輪的話什么也看不到,所以第一次進頁面需要調(diào)用checkShow(),處于視野中的圖片也加載出來。
在代碼最后加上:
// 第一次進頁面加載處于視野中的圖片
Array.prototype.slice.apply(document.getElementsByTagName('li')).forEach((li)=>{
let img=li.getElementsByTagName('img')[0];
// 判斷當(dāng)前img是否出現(xiàn)在了視野中
// 判斷當(dāng)前img是否被加載過了
if(checkShow(img) && !isLoaded(img)){
loadImg(img);
}
})
此時我們發(fā)現(xiàn)判斷加載視野中的圖片代碼存在重復(fù),直接封裝成一個新的方法lazyRenderImg();
// window綁定滾動事件
window.addEventListener('scroll',function(){
// 遍歷所有的img標簽
lazyRenderImg();
});
function lazyRenderImg(){
Array.prototype.slice.apply(document.getElementsByTagName('li')).forEach((li)=>{
let img=li.getElementsByTagName('img')[0];
// 判斷當(dāng)前img是否出現(xiàn)在了視野中
// 判斷當(dāng)前img是否被加載過了
if(checkShow(img) && !isLoaded(img)){
loadImg(img);
}
})
}
// 第一次進頁面加載處于視野中的圖片
lazyRenderImg();
三.性能優(yōu)化
問題:window.scroll 方法頁面只要一滾動就會觸發(fā)里面的方法,對性能影響很大
解決方法:當(dāng)頁面停止?jié)L動的時候,再去執(zhí)行頁面中的方法,類似與函數(shù)節(jié)流(throttle)
Tips:函數(shù)節(jié)流:等時間間隔執(zhí)行函數(shù), 讓一個函數(shù)不要執(zhí)行得太頻繁,減少一些過快的調(diào)用來節(jié)流。
// window綁定滾動事件
let timer;
window.addEventListener('scroll',function(){
console.log('scroll')
// 遍歷所有的img標簽
if(timer){
clearTimeout(timer)
}
timer=setTimeout(()=>{
console.log('lazyRenderImg...');
lazyRenderImg();
},300);
通過打印的日志發(fā)現(xiàn)當(dāng)滾動停止后才執(zhí)行lazyRenderImg方法的,確實減少了不必要調(diào)用lazyRenderImg的次數(shù)。

以上所述是小編給大家介紹的原生JS實現(xiàn)圖片懶加載之頁面性能優(yōu)化,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復(fù)大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!
如果你覺得本文對你有幫助,歡迎轉(zhuǎn)載,煩請注明出處,謝謝!
相關(guān)文章
使用JS+XML(數(shù)據(jù)島)實現(xiàn)分頁)
使用JS+XML(數(shù)據(jù)島)實現(xiàn)分頁)...2007-01-01
JS求1到任意數(shù)之間的所有質(zhì)數(shù)的方法詳解
這篇文章主要介紹了JS求1到任意數(shù)之間的所有質(zhì)數(shù),本文通過實例代碼給大家介紹的非常詳細,具有一定的參考借鑒價值 ,需要的朋友可以參考下2019-05-05
JavaScript安全加密之禁止別人調(diào)試自己的前端頁面代碼實現(xiàn)
這篇文章主要為大家介紹了JavaScript安全加密之如何禁止別人調(diào)試自己的前端頁面代碼實現(xiàn),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-08-08
uni-app基本的數(shù)據(jù)綁定v-bind,v-for,v-on:click詳解
這篇文章主要介紹了uni-app基本的數(shù)據(jù)綁定v-bind,v-for,v-on:click,本文通過示例代碼給大家介紹的非常詳細,需要的朋友可以參考下2024-08-08

