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

背景

當我們進行窗口resize、scroll挨厚、input框內(nèi)容校驗等操作時,如果事件函數(shù)調(diào)用頻率不加控制甥材。會加重瀏覽器的負擔绑改,導致用戶體驗度差谢床。此時我們可以在不影響功能效果的前提下使用函數(shù)防抖和函數(shù)節(jié)流的方式來減少調(diào)用頻率。

防抖和節(jié)流

防抖

debounce厘线,當事件觸發(fā)事件時识腿,一定時間段t內(nèi)沒有再次觸發(fā)事件,事件處理函數(shù)才會執(zhí)行皆的,如果在時間段t內(nèi)覆履,又觸發(fā)了一次函數(shù),就重新開始延時费薄,即再過t時間后執(zhí)行硝全。

在我們的開發(fā)過程中,比如resize楞抡、scroll伟众、mousemove、mouseover等召廷,會頻發(fā)的觸發(fā)凳厢,如果不做限制的話,有可能1s內(nèi)執(zhí)行了幾十次竞慢、上百次先紫。如果在這些函數(shù)內(nèi)執(zhí)行了其他函數(shù),尤其是執(zhí)行了操作DOM的函數(shù)筹煮,那不僅僅會造成計算機資源的浪費遮精,還會降低程序運行速度,甚至會照成瀏覽器卡死败潦、崩潰本冲。

防抖的關(guān)鍵在于,在一個動作發(fā)生 一定時間之后劫扒,才執(zhí)行特定的事件檬洞。

let debounce = function(fn, delay = 500) {
  if (typeof fn !== "function") {
    throw new TypeError("Expected a function");
  }
  let timer = null;
  return (...arg) => {
    if (timer) {
      clearTimeout(timer);
    }
    timer = setTimeout(function() {
      fn.call(arg);
    }, delay);
  };
};

過程分析:

  1. 第一次觸發(fā)事件,不立即執(zhí)行
  2. delay時間內(nèi)沟饥,再次觸發(fā)事件添怔,清除定時器,重新開始計時
  3. delay時間后贤旷,執(zhí)行函數(shù)
1583948499007.png

通常情況下函數(shù)在觸發(fā)事件后一直等待广料,我們可以在第一次時間出觸發(fā)后立即執(zhí)行,但仍保持delay時間內(nèi)多次觸發(fā)只執(zhí)行一次遮晚。lodash.debounce通過leadingtrailing來控制函數(shù)在delay前執(zhí)行性昭,還是delay后執(zhí)行。在underscore.js通過immdiate通知執(zhí)行的時機县遣。

1583948542942.png

適用場景:

  1. resize時間
  2. 觸發(fā)ajax請求

節(jié)流

throttle糜颠,當持續(xù)觸發(fā)事件時,保證一定時間段t內(nèi)只調(diào)用一次事件處理函數(shù)萧求。

側(cè)重于一段時間內(nèi)其兴,執(zhí)行一次。

let throttle = function(fn, delay = 400) {
  if (typeof fn !== "function") {
    throw new TypeError("Expected a function");
  }
  let flag = true;
  return function(...args) {
    if (!flag) return;
    flag = false;
    setTimeout(() => {
      fn(...args);
      flag = true;
    }, delay);
  };
};

過程分析:

  1. 第一次觸發(fā)事件夸政,元旬,開關(guān)項置為false
  2. delay時間段內(nèi),再次觸發(fā),不新計時
  3. delay時間后執(zhí)行函數(shù)匀归,并設(shè)置開關(guān)為true
  4. 再次觸發(fā)事件,開關(guān)項置為false
  5. 距離上次觸發(fā)delay時間內(nèi)坑资,不執(zhí)行函數(shù)
  6. 距離上次觸發(fā)delay時間后,執(zhí)行函數(shù)穆端,并設(shè)置開關(guān)true
1583952137879.png

適用場景:

  1. scroll事件
  2. 重復點擊事件

區(qū)別

防抖:時間段內(nèi)多次觸發(fā)袱贮,只執(zhí)行最后一次

節(jié)流:每隔固定時間段后保證穩(wěn)定執(zhí)行一次

一句話:防抖是將多次執(zhí)行變?yōu)橐淮螆?zhí)行,節(jié)流是將多次執(zhí)行變?yōu)槊扛粢欢螘r間執(zhí)行

requestAnimationFrame

可以認為它是一個_.throttle(dosomething, 16)体啰。但保真度更高攒巍,因為它是旨在提高準確性的瀏覽器本機API。

requestAnimationFrame接受一個動畫執(zhí)行函數(shù)作為參數(shù)荒勇,這個函數(shù)的作用是僅執(zhí)行一幀動畫的渲染柒莉,并根據(jù)條件判斷是否結(jié)束,如果動畫沒有結(jié)束沽翔,則繼續(xù)調(diào)用requestAnimationFrame并將自身作為參數(shù)傳入

優(yōu)點:

  1. 以60FPS(每幀16ms)為目標兢孝,瀏覽器內(nèi)部會選擇渲染的最佳時機
  2. API簡單

缺點:

  1. 需要手動啟動和取消
  2. node.js不支持

適用場景:

  1. 函數(shù)是“繪畫”
  2. 直接對屬性進行動畫處理

參考:

https://css-tricks.com/debouncing-throttling-explained-examples/

https://juejin.im/post/5b8de829f265da43623c4261

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市搀擂,隨后出現(xiàn)的幾起案子西潘,更是在濱河造成了極大的恐慌,老刑警劉巖哨颂,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件喷市,死亡現(xiàn)場離奇詭異,居然都是意外死亡威恼,警方通過查閱死者的電腦和手機品姓,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來箫措,“玉大人腹备,你說我怎么就攤上這事〗锫” “怎么了植酥?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長弦牡。 經(jīng)常有香客問我友驮,道長,這世上最難降的妖魔是什么驾锰? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任卸留,我火速辦了婚禮,結(jié)果婚禮上椭豫,老公的妹妹穿的比我還像新娘耻瑟。我一直安慰自己旨指,他們只是感情好,可當我...
    茶點故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布喳整。 她就那樣靜靜地躺著谆构,像睡著了一般。 火紅的嫁衣襯著肌膚如雪算柳。 梳的紋絲不亂的頭發(fā)上低淡,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天姓言,我揣著相機與錄音瞬项,去河邊找鬼。 笑死何荚,一個胖子當著我的面吹牛囱淋,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播餐塘,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼妥衣,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了戒傻?” 一聲冷哼從身側(cè)響起税手,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎需纳,沒想到半個月后芦倒,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡不翩,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年兵扬,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片口蝠。...
    茶點故事閱讀 40,040評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡器钟,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出妙蔗,到底是詐尸還是另有隱情傲霸,我是刑警寧澤,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布眉反,位于F島的核電站昙啄,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏禁漓。R本人自食惡果不足惜跟衅,卻給世界環(huán)境...
    茶點故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望播歼。 院中可真熱鬧伶跷,春花似錦掰读、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至雇初,卻和暖如春拢肆,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背靖诗。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工郭怪, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人刊橘。 一個月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓鄙才,卻偏偏與公主長得像,于是被迫代替她去往敵國和親促绵。 傳聞我的和親對象是個殘疾皇子攒庵,可洞房花燭夜當晚...
    茶點故事閱讀 44,979評論 2 355

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