節流和防抖

一、事件防抖

在前端開發中,有時會爲頁面綁定resize事件,或者爲一個頁面元素綁定拖拽事件(mousemove),這種事件有一個特色,在一個正常的操做中,有可能在一個短的時間內觸發很是屢次事件綁定程序。
DOM操做時很消耗性能的,若是你爲這些事件綁定一些操做DOM節點的操做的話,那就會引起大量的計算,在用戶看來,頁面可能就一時間沒有響應,這個頁面一會兒變卡了變慢了。在IE下,若是你綁定的resize事件進行較多DOM操做可能直接就崩潰了。html

這個你輕輕一拖,就會執行幾十次,這對性能不友好的。前端

輸入完成後統一發送請求,最後一我的說了算,只認最後一次瀏覽器

若是用戶每次輸入都發送請求,冗餘過多,用戶中止輸入字符350毫秒後,在發送請求app

window.onscroll=function() {
     console.log("滾動")
 }
function debounce(fn, delay) {
  var timer = null;
  return function () {
    var context = this, args = arguments;
    clearTimeout(timer);
    timer = setTimeout(function () {
      fn.apply(context, args);
    }, delay);
  };
}

使用,會發現次數明顯的下降了函數

window.onscroll = debounce(function () {
            console.log("啊哈哈")
  }, 100)

應用場景性能

  • search搜索聯想,用戶在不斷輸入值時,用防抖來節約請求資源。
  • window觸發resize的時候,不斷的調整瀏覽器窗口大小會不斷的觸發這個事件,用防抖來讓其只觸發一次

二、函數節流

某一段時間只執行一次,好比說350ms固定發送請求this

function throttle(fn, threshhold, scope) {
  threshhold || (threshhold = 250);
  var last,
      deferTimer;
  return function () {
    var context = scope || this;

    var now = +new Date,
        args = arguments;
    if (last && now < last + threshhold) {
      // hold on to it
      clearTimeout(deferTimer);
      deferTimer = setTimeout(function () {
        last = now;
        fn.apply(context, args);
      }, threshhold);
    } else {
      last = now;
      fn.apply(context, args);
    }
  };
}


$('body').on('mousemove', throttle(function (event) {
  console.log('tick');
}, 1000));

應用場景.net

  • 鼠標不斷點擊觸發,mousedown(單位時間內只觸發一次)
  • 監聽滾動事件,好比是否滑到底部自動加載更多,用throttle來判斷

網上有這段話code


什麼玩意兒???這麼麻煩的嗎?防抖還好,大部分都能達到理想的效果,但是節流就沒那麼理想了。節流是技能冷卻啊!就是要點一下立馬觸發,進入冷卻,等冷卻,結束繼續能點。然而大多版本都是:點擊等一下子才觸發,進入冷卻。前面多了莫名的等待時間,不是立馬觸發的.......htm

三、參考連接

關於Js debounce 函數小結

函數節流外國的一篇文章

7分鐘理解JS的節流、防抖及使用場景

最精簡的節流和防抖