防抖和節(jié)流

一、防抖(debounce)
某一操作在規(guī)定時(shí)間內(nèi)再未觸發(fā),則執(zhí)行回調(diào),若觸發(fā),則重新計(jì)時(shí)。

let start = +new Date();
//聲明一個(gè)柯里化函數(shù)
function debounce(fun, delay){
    return function(args){
        let that = this;
        //執(zhí)行該語(yǔ)句時(shí)若距離上次執(zhí)行時(shí)間未超過(guò)delay毫秒,則在定時(shí)器執(zhí)行前清除該
        //定時(shí)器,并啟用新的定時(shí)器
        //反之超過(guò)delay毫秒,定時(shí)器ID(fun.id)對(duì)應(yīng)的定時(shí)器已執(zhí)行
        clearTimeout(fun.id);                       
        fun.id = setTimeout(function(){        //delay時(shí)長(zhǎng)后,執(zhí)行定時(shí)器
            fun.call(that, args)
        },delay)
    }        
}
let con = function(){
    console.log(+new Date - start);
}
let highFun = debounce(con, 1000);
setInterval(highFun, 300);    //沒(méi)有打印
setInterval(highFun, 3000);  //第一次4s后打印,之后每隔3s打印

應(yīng)用場(chǎng)景:
1、用戶(hù)輸入觸發(fā)請(qǐng)求發(fā)送或者窗口更新時(shí),應(yīng)用debounce減少請(qǐng)求和更新頻率。

二、節(jié)流(debounce)
規(guī)定時(shí)間內(nèi)只觸發(fā)一次,該時(shí)間內(nèi)的其余觸發(fā)無(wú)效。

let start = +new Date();
let con = function(){
    console.log(+new Date - start);
}
function throttle(fn, delay){
    let last, stid;
    return function(args){
        let that = this;
        let time = +new Date();
        //如果第一次執(zhí)行或者距離上次執(zhí)行超過(guò)delay,則執(zhí)行下一次操作
        if(!last || time - last > delay){  
            last = time;
            fn.apply(that, args)
        }
    }
}
//每10ms嘗試執(zhí)行打印操作,實(shí)際每約1s執(zhí)行一次 
setInterval(throttle(con, 1000), 10);

應(yīng)用場(chǎng)景:
1、canvas動(dòng)畫(huà)中,結(jié)合requestAnimationFrame來(lái)控制人物每秒移動(dòng)的距離
2、發(fā)送請(qǐng)求時(shí),在回調(diào)成功前阻止請(qǐng)求多次發(fā)送
3、窗口的scroll事件中,滑動(dòng)一定時(shí)間或距離后執(zhí)行自定義操作

三、分時(shí)函數(shù)
當(dāng)遇到一次性大量渲染時(shí),嘗試將大任務(wù)分割成小任務(wù)延時(shí)完成。

//  arr: 源數(shù)據(jù)
//  process: 處理函數(shù)
//  count: 每次抽取個(gè)數(shù)
var chunk = function(arr, process, count){
    setTimeout(function(){
        for(var i = 0, len = Math.min(count, arr.length); i < len; i++) {
            //取出數(shù)組中的第一個(gè)數(shù)據(jù)進(jìn)行處理,并在源數(shù)據(jù)中刪除
            process(arr.shift());    
        }
        if(arr.length > 0) {
            //若有剩余任務(wù),則100ms后調(diào)用自身繼續(xù)處理
            setTimeout(arguments.callee, 100);  
        }
    }, 100);
}

應(yīng)用場(chǎng)景:
1、處理大量DOM渲染時(shí),分割成小任務(wù)以減輕瀏覽器壓力。

四、總結(jié):
防抖節(jié)流以及分時(shí)函數(shù)的本質(zhì)都是限制函數(shù)的高頻觸發(fā)來(lái)提高頁(yè)面性能。

參考文章:
https://juejin.im/post/5b8de829f265da43623c4261
https://juejin.im/entry/5815876c8ac247004fb6d132/

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀(guān)點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容