JavaScript深入理解節(jié)流與防抖_第1頁
JavaScript深入理解節(jié)流與防抖_第2頁
JavaScript深入理解節(jié)流與防抖_第3頁
JavaScript深入理解節(jié)流與防抖_第4頁
JavaScript深入理解節(jié)流與防抖_第5頁
已閱讀5頁,還剩5頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

第JavaScript深入理解節(jié)流與防抖目錄一、js防抖和節(jié)流二、為什么滾動scroll、窗口resize等事件需要優(yōu)化三、滾動和頁面渲染前端性能優(yōu)化的關(guān)系四、防抖Debounce1防抖Debounce情景2防抖原理3防抖函數(shù)簡單實現(xiàn)4防抖函數(shù)的演化過程①thisevent綁定問題②立即觸發(fā)問題③返回值問題④取消防抖,添加cancel方法五、節(jié)流Throttle1節(jié)流Throttle情景2節(jié)流原理3節(jié)流實現(xiàn)時間戳和定時器4節(jié)流函數(shù)的演化過程①時間戳觸發(fā)②定時器觸發(fā)③結(jié)合時間戳和定時器六、節(jié)流防抖總結(jié)

一、js防抖和節(jié)流

在進行窗口的resize、scroll、輸出框內(nèi)容校驗等操縱的時候,如果事件處理函數(shù)調(diào)用的頻率無限制,會加重瀏覽器的負擔,導致用戶體驗非常之差。那么為了前端性能的優(yōu)化也為了用戶更好的體驗,就可以采用防抖(debounce)和節(jié)流(throttle)的方式來到達這種效果,減少調(diào)用的頻率。

二、為什么滾動scroll、窗口resize等事件需要優(yōu)化

滾動事件的應(yīng)用很頻繁:圖片懶加載、下滑自動加載數(shù)據(jù)、側(cè)邊浮動導航欄等。

在綁定scroll、resize事件時,但它發(fā)生的時候,它被觸發(fā)的頻率非常高,間隔很近。在日常開發(fā)的頁面中,事件中涉及到的大量的位置計算、DOM操作、元素重繪等等這些都無法在下一個scroll事件出發(fā)前完成的情況下,瀏覽器會卡幀。

三、滾動和頁面渲染前端性能優(yōu)化的關(guān)系

為什么滾動需要優(yōu)化?前面提到了事件中涉及到大量的位置計算、DOM操作、元素重繪等等,這些又與頁面的渲染有關(guān)系,頁面渲染又與前端的性能優(yōu)化有關(guān)系?套娃一樣,一層套著一層,每一層都聯(lián)系緊密,每一層都如此平凡且重要。

review一下前端的渲染和優(yōu)化

web頁面展示經(jīng)歷的步驟:jsstylelayoutpaintcomposite,簡單回顧一下,在這里不做詳細的介紹哦!

網(wǎng)頁生成的時候,至少會渲染(Layout+Paint)一次。用戶訪問的過程中,還會不斷重新的重排(reflow)和重繪(repaint),用戶scroll行為和resize行為會導致頁面不斷的進行重新渲染,而且間隔頻繁,容易造成瀏覽器卡幀。

四、防抖Debounce

1防抖Debounce情景

①有些場景事件觸發(fā)的頻率過高(mousemoveonkeydownonkeyuponscroll)

②回調(diào)函數(shù)執(zhí)行的頻率過高也會有卡頓現(xiàn)象??梢砸欢螘r間過后進行觸發(fā)去除無用操作

2防抖原理

一定在事件觸發(fā)n秒后才執(zhí)行,如果在一個事件觸發(fā)的n秒內(nèi)又觸發(fā)了這個事件,以新的事件的時間為準,n秒后才執(zhí)行,等觸發(fā)事件n秒內(nèi)不再觸發(fā)事件才執(zhí)行。

官方解釋:當持續(xù)觸發(fā)事件時,一定時間段內(nèi)沒有再觸發(fā)事件,事件處理函數(shù)才會執(zhí)行一次,如果設(shè)定的時間到來之前,又一次觸發(fā)了事件,就重新開始延時。

3防抖函數(shù)簡單實現(xiàn)

//簡單的防抖函數(shù)

functiondebounce(func,wait,immediate){

//定時器變量

vartimeout;

returnfunction(){

//每次觸發(fā)scrolle,先清除定時器

clearTimeout(timeout);

//指定多少秒后觸發(fā)事件操作handler

timeout=setTimeout(func,wait);

//綁定在scrolle事件上的handler

functionhandlerFunc(){

console.log('Success');

//沒采用防抖動

window.addEventListener('scroll',handlerFunc);

//采用防抖動

window.addEventListener('scrolle',debounce(handlerFunc,1000));

4防抖函數(shù)的演化過程

①thisevent綁定問題

//以閉包的形式返回一個函數(shù),內(nèi)部解決了this指向的問題,event對象傳遞的問題

functiondebounce(func,wait){

vartimeout;

returnfunction(){

varcontext=this;

varargs=arguments;

clearTimeout(timeout)

timeout=setTimeout(function(){

func.apply(context,args)

},wait);

②立即觸發(fā)問題

//首次觸發(fā)執(zhí)行,再次觸發(fā)以后開始執(zhí)行防抖函數(shù)

//使用的時候不用重復執(zhí)行這個函數(shù),本身返回的函數(shù)才具有防抖功能

functiondebounce(func,wait,immediate){

vartimeout;

returnfunction(){

varcontext=this;

varargs=arguments;

if(timeout)clearTimeout(timeout);

//是否在某一批事件中首次執(zhí)行

if(immediate){

varcallNow=!timeout;

timeout=setTimeout(function(){

timeout=null;

func.apply(context,args)

immediate=true;

},wait);

if(callNow){

func.apply(context,args)

immediate=false;

}else{

timeout=setTimeout(function(){

func.apply(context,args);

immediate=true;

},wait);

③返回值問題

functiondebounce(func,wait,immediate){

vartimeout,result;

returnfunction(){

varcontext=this,args=arguments;

if(timeout)clearTimeout(timeout);

if(immediate){

varcallNow=!timeout;

timeout=setTimeout(function(){

result=func.apply(context,args)

},wait);

if(callNow)result=func.apply(context,args);

}else{

timeout=setTimeout(function(){

result=func.apply(context,args)

},wait);

returnresult;

④取消防抖,添加cancel方法

functiondebounce(func,wait,immediate){

vartimeout,result;

functiondebounced(){

varcontext=this,args=arguments;

if(timeout)clearTimeout(timeout);

if(immediate){

varcallNow=!timeout;

timeout=setTimeout(function(){

result=func.apply(context,args)

},wait);

if(callNow)result=func.apply(context,args);

}else{

timeout=setTimeout(function(){

result=func.apply(context,args)

},wait);

returnresult;

debounced.cancel=function(){

cleatTimeout(timeout);

timeout=null;

returndebounced;

五、節(jié)流Throttle

1節(jié)流Throttle情景

①圖片懶加載

②ajax數(shù)據(jù)請求加載

2節(jié)流原理

如果持續(xù)觸發(fā)事件,每隔一段時間只執(zhí)行一次函數(shù)。

官方解釋:當持續(xù)觸發(fā)事件時,保證一定時間段內(nèi)只調(diào)用一次事件處理函數(shù)。

3節(jié)流實現(xiàn)時間戳和定時器

時間戳

varthrottle=function(func,delay){

varprev=Date.now()

returnfunction(){

varcontext=this;

varargs=arguments;

varnow=Date.now();

if(now-prev=delay){

func.apply(context,args);

prev=Date.now();

functionhandle(){

console.log(Math.random());

window.addEventListener('scroll',throttle(handle,1000));

定時器

varthrottle=function(func,delay){

vartimer=null;

returnfunction(){

varcontext=this;

varargs=arguments;

if(!timer){

timer=setTimeout(function(){

func.apply(context,args);

timer=null;

},delay);

functionhandle(){

console.log(Math.random());

window.addEventListener('scroll',throttle(handle,1000))

4節(jié)流函數(shù)的演化過程

①時間戳觸發(fā)

//在開始觸發(fā)時,會立即執(zhí)行一次;如果最后一次沒有超過wait值,則不觸發(fā)

functionthrottle(func,wait){

varcontext,args;

varprevious=0;//初始的時間點,也是關(guān)鍵的時間點

returnfunction(){

varnow=+newDate();

context=this;

args=arguments;

if(now-previouswait){

func.apply(context,args);

previous=now;

②定時器觸發(fā)

//首次不會立即執(zhí)行,最后一次會執(zhí)行,和用時間戳的寫法互補。

functionthrottle(func,wait){

varcontext,args,timeout;

returnfunction(){

context=this;

args=arguments;

if(!timeout){

timeout=setTimeout(function(){

func.apply(context,args);

timeout=null;

},wait);

③結(jié)合時間戳和定時器

functionthrottle(func,wait){

vartimer=null;

varstartTime=Date.now();

returnfunction(){

varcurTime=Date.now();

varremaining=wait-(curTime-startTime);

varcontext=this;

varargs=arguments;

clearTimeout(timer);

if(remaining=0){

func.apply(context,args);

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論