圖片懶加載
定義:就是這張圖片很懶,喜歡臨時(shí)抱佛腳瞳氓,都到了出現(xiàn)在屏幕視線范圍內(nèi)了才加載策彤。不過(guò)懶人有懶福栓袖,這樣可以在那種有大量圖片需要展示的網(wǎng)站上優(yōu)化性能,減輕瀏覽器壓力店诗,畢竟你要瀏覽器一次加載一兩百?gòu)垐D片也很累
原理: 每個(gè)圖片標(biāo)簽先把圖片地址存儲(chǔ)在一個(gè)臨時(shí)屬性上裹刮,用瀏覽器的onscroll事件監(jiān)聽每個(gè)圖片元素,到了屏幕可視區(qū)域再賦予地址到src上庞瘸。
代碼實(shí)現(xiàn):
html代碼 省略
js代碼
const imgs = document.querySelectorAll('img');
let begin = 0;
function lazyload(){
for (let index = begin; index < imgs.length; index++) {
const img = imgs[index];
if(img.offsetTop < document.documentElement.clientHeight + document.documentElement.scrollTop){
console.log("scroll"+index+"到了")
begin = index; //不去遍歷已經(jīng)加載了得圖片
img.src = img.getAttribute("imgPath")
}
}
}
lazyload() //渲染首屏捧弃,先執(zhí)行一次
window.onscroll = lazyload;
以上代碼缺點(diǎn),執(zhí)行太多了擦囊,每次監(jiān)聽到滾輪事件都要去循環(huán)
添加個(gè)節(jié)流函數(shù):违霞,如下:
//節(jié)流函數(shù)
function throttle(lazyTime, Fuc){
var lastTime = null //記錄上次時(shí)間
return function(){
var currentTime = new Date().getTime();
if(!lastTime){ //初始化時(shí)間
lastTime = currentTime;
}
if(lastTime + lazyTime < currentTime){
Fuc();
lastTime = currentTime;
}
}
}
window.onscroll = throttle(50, lazyload) //事件回調(diào)是個(gè)閉包
測(cè)試基本可行,沒在項(xiàng)目中跑過(guò)瞬场,可能待優(yōu)化的地方還比較多买鸽,原理是這樣的
建議自己多自己寫下,紙上得來(lái)終覺淺贯被,絕知此事要躬行
說(shuō)到了節(jié)流眼五,又要說(shuō)下防抖函數(shù),現(xiàn)學(xué)現(xiàn)賣彤灶,以前我不知道二者的區(qū)別看幼,但是在項(xiàng)目中已經(jīng)不知不覺用過(guò)了。
節(jié)流函數(shù):不管事件的觸發(fā)頻率有多高幌陕,只會(huì)間隔設(shè)定的時(shí)間執(zhí)行目標(biāo)函數(shù)诵姜,如模糊搜索,上面的懶加載苞轿,規(guī)定時(shí)間內(nèi)必執(zhí)行
防抖函數(shù): 當(dāng)觸發(fā)頻率高于設(shè)定的值得時(shí)候茅诱,不執(zhí)行。低于觸發(fā)頻率再執(zhí)行搬卒。
解釋起來(lái)很模糊瑟俭。
實(shí)際運(yùn)用中,如:需要后臺(tái)驗(yàn)證的用戶名注冊(cè)輸入框契邀,當(dāng)用戶頻繁輸入的時(shí)候不用驗(yàn)證摆寄,當(dāng)用戶有一個(gè)停頓的時(shí)候,去后臺(tái)驗(yàn)證是否重名坯门,這樣優(yōu)化了交互微饥,減輕了服務(wù)器壓力
上代碼:
html
<h1>注冊(cè)</h1>
<p id="text"></p>
<input type="text" id="input">
js
function debounce(Fuc, time){ //防抖
let timer = null
return function () {
clearTimeout(timer);
//清除定時(shí)器,如果觸發(fā)時(shí)間超過(guò)設(shè)定時(shí)間古戴,則定時(shí)器中的代碼不能執(zhí)行
timer = setTimeout(() => {
Fuc()
}, time); //重新賦值定時(shí)器
}
}
function test(){
document.querySelector('#text').innerHTML = new Date().getTime();
}
document.querySelector('#input').addEventListener('input', debounce(test, 1000))
原理很簡(jiǎn)單欠橘,利用閉包操作同一個(gè)定時(shí)器的原理,和定時(shí)器的異步性现恼,觸發(fā)時(shí)間短于設(shè)定時(shí)間時(shí)肃续,去清除還沒有執(zhí)行的定時(shí)器黍檩,然后重新定義定時(shí)器。很巧妙的代碼
效果圖:
輸入前:
頻繁輸入過(guò)程中:
輸入停止1s后: