JS函數(shù)節(jié)流防抖

在前端開發(fā)中有一部分的用戶行為會頻繁的觸發(fā)事件執(zhí)行,而對于DOM操作其掂、資源加載等耗費性能的處理款熬,很可能導(dǎo)致界面卡頓华烟,甚至瀏覽器的崩潰。函數(shù)節(jié)流(throttle)和函數(shù)防抖(debounce)就是為了解決類似需求應(yīng)運而生的负饲。



原文鏈接

函數(shù)節(jié)流(throttle)

函數(shù)節(jié)流就是預(yù)定一個函數(shù)只有在大于等于執(zhí)行周期時才執(zhí)行返十,周期內(nèi)調(diào)用不執(zhí)行洞坑。好像水滴攢到一定重量才會落下一樣蝇率。

場景:

  • 窗口調(diào)整(resize)
  • 頁面滾動(scroll)
  • 搶購瘋狂點擊(mousedown)

實現(xiàn):

function throttle(method, delay){
    var last = 0;
    return function (){
        var now = +new Date();
        if(now - last > delay){
            method.apply(this,arguments);
            last = now;
        }
    }
}

document.getElementById('throttle').onclick = throttle(function(){console.log('click')},2000);

underscore實現(xiàn):

_.throttle = function(func, wait, options) {
    var context, args, result;
    var timeout = null;
    var previous = 0;
    if (!options) options = {};
    var later = function() {
        previous = options.leading === false ? 0 : _.now();
        timeout = null;
        result = func.apply(context, args);
        if (!timeout) context = args = null;
    };
    return function() {
        var now = _.now();
        if (!previous && options.leading === false) previous = now;
        //計算剩余時間
        var remaining = wait - (now - previous);
        context = this;
        args = arguments;
        //剩余時間小于等于0或者剩余時間大于等待時間(本地時間變動出現(xiàn))
        if (remaining <= 0 || remaining > wait) {
            if (timeout) {
                clearTimeout(timeout);
                timeout = null;
            }
            previous = now;
            result = func.apply(context, args);
            if (!timeout) context = args = null;
        } else if (!timeout && options.trailing !== false) {
            timeout = setTimeout(later, remaining);
        }
        return result;
    };
};    

函數(shù)防抖(debounce)

函數(shù)防抖就是在函數(shù)需要頻繁觸發(fā)情況時排拷,只有足夠空閑的時間,才執(zhí)行一次布蔗。好像公交司機會等人都上車后才出站一樣纵揍。

場景:

  • 實時搜索(keyup)
  • 拖拽(mousemove)

實現(xiàn):

function debounce(method, delay){
    var timer = null;
    return function(){
        var context = this,args = arguments;
        clearTimeout(timer);
        timer = setTimeout(function(){
            method.apply(context, args);
        },delay);
    }
}

document.getElementById('debounce').onclick = debounce(function(){console.log('click')},2000);

underscore實現(xiàn):

_.debounce = function(func, wait, immediate) {
    var timeout, args, context, timestamp, result;
    var later = function() {
        var last = _.now() - timestamp;
        if (last < wait && last >= 0) {
            timeout = setTimeout(later, wait - last);
        } else {
            timeout = null;
            if (!immediate) {
                result = func.apply(context, args);
                if (!timeout) context = args = null;
            }
        }
    };
    return function() {
        context = this;
        args = arguments;
        timestamp = _.now();
        var callNow = immediate && !timeout;
        if (!timeout) timeout = setTimeout(later, wait);
        if (callNow) {
            result = func.apply(context, args);
            context = args = null;
        }
        return result;
    };
};    

函數(shù)節(jié)流(throttle)和函數(shù)防抖(debounce)都是通過延時邏輯操作來提升性能的方法,在前端優(yōu)化中是常見且重要的解決方式特漩。可以從概念和實際應(yīng)用中理解兩者的區(qū)別,在需要的時候選擇合適的方法處理访得。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末悍抑,一起剝皮案震驚了整個濱河市杜耙,隨后出現(xiàn)的幾起案子佑女,更是在濱河造成了極大的恐慌,老刑警劉巖团驱,帶你破解...
    沈念sama閱讀 217,542評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件嚎花,死亡現(xiàn)場離奇詭異紊选,居然都是意外死亡道逗,警方通過查閱死者的電腦和手機滓窍,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評論 3 394
  • 文/潘曉璐 我一進店門贰您,熙熙樓的掌柜王于貴愁眉苦臉地迎上來锦亦,“玉大人令境,你說我怎么就攤上這事舔庶。” “怎么了瞧甩?”我有些...
    開封第一講書人閱讀 163,912評論 0 354
  • 文/不壞的土叔 我叫張陵肚逸,是天一觀的道長朦促。 經(jīng)常有香客問我栓始,道長幻赚,這世上最難降的妖魔是什么坯屿? 我笑而不...
    開封第一講書人閱讀 58,449評論 1 293
  • 正文 為了忘掉前任领跛,我火速辦了婚禮,結(jié)果婚禮上喊括,老公的妹妹穿的比我還像新娘郑什。我一直安慰自己蘑拯,他們只是感情好钝满,可當我...
    茶點故事閱讀 67,500評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著申窘,像睡著了一般弯蚜。 火紅的嫁衣襯著肌膚如雪溅潜。 梳的紋絲不亂的頭發(fā)上陷寝,一...
    開封第一講書人閱讀 51,370評論 1 302
  • 那天哟绊,我揣著相機與錄音葡缰,去河邊找鬼。 笑死一膨,一個胖子當著我的面吹牛缴啡,可吹牛的內(nèi)容都是我干的砸讳。 我是一名探鬼主播优构,決...
    沈念sama閱讀 40,193評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼诵叁,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了钦椭?” 一聲冷哼從身側(cè)響起黎休,我...
    開封第一講書人閱讀 39,074評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后盲厌,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,505評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,722評論 3 335
  • 正文 我和宋清朗相戀三年映砖,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片地技。...
    茶點故事閱讀 39,841評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖食磕,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤搂橙,帶...
    沈念sama閱讀 35,569評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站礁芦,受9級特大地震影響诀豁,放射性物質(zhì)發(fā)生泄漏活翩。R本人自食惡果不足惜材泄,卻給世界環(huán)境...
    茶點故事閱讀 41,168評論 3 328
  • 文/蒙蒙 一魁巩、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦集晚、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽钙蒙。三九已至竞帽,卻和暖如春疙渣,著一層夾襖步出監(jiān)牢的瞬間啦租,已是汗流浹背内地。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人勺像。 一個月前我還...
    沈念sama閱讀 47,962評論 2 370
  • 正文 我出身青樓辰狡,卻偏偏與公主長得像叫倍,于是被迫代替她去往敵國和親蚕泽。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,781評論 2 354

推薦閱讀更多精彩內(nèi)容

  • 函數(shù)節(jié)流 還記得上篇文章中說到的圖片懶加載嗎徐钠?我們在文章的最后實現(xiàn)了一個頁面滾動時按需加載圖片的方式,即在觸發(fā)滾動...
    柏丘君閱讀 2,846評論 1 19
  • 其實早就聽說了節(jié)流和防抖的解決方案。這兩個的目的都是為了提升頁面中監(jiān)聽事件的性能蛤迎。才疏學(xué)淺,如果有錯誤窘问,也希望各位...
    Katherine的小世界閱讀 1,892評論 0 6
  • UnderScore對象封裝 Underscore像jQuery一樣儿咱,將數(shù)據(jù)封裝在一個自定義對象中——Unders...
    小淘氣_嘻閱讀 1,113評論 0 0
  • 前端菜鳥一只,查閱了一些資料,大概明白了什么是函數(shù)節(jié)流 是什么罐呼? 就是讓一個函數(shù)無法在很短的時間間隔內(nèi)連續(xù)執(zhí)行计螺,只...
    莊海鑫閱讀 1,750評論 2 3
  • 昨天,伱載我回家,因為沒有說清地點揍愁,讓你多等了一會朽缎。你就開始有小情緒了。雖然我道歉了谜悟,可是我也介懷了话肖。 我...
    凌琦閱讀 220評論 0 0