debounce(防抖)和throttle(節流)

防抖和節流

窗口的resizescroll,輸入框內容校驗等操做時,若是這些操做處理函數較爲複雜或頁面頻繁重渲染等操做時,若是事件觸發的頻率無限制,會加劇瀏覽器的負擔,致使用戶體驗很是糟糕。此時咱們能夠採用debounce(防抖)和throttle(節流)的方式來減小觸發的頻率,同時又不影響實際效果。javascript

debounce 防抖

debounce(防抖),簡單來講就是防止抖動。html

debounce 防抖

從上圖中咱們能夠看到,當持續觸發事件時,debounce會合並事件且不會去觸發事件,當必定時間內沒有觸發再這個事件時,才真正去觸發事件~ 一塊兒來實現個簡單的debounce:java

function debounce(fn, delay) {
  var ctx;
  var args;
  var timer = null;

  var later = function () {
    fn.apply(ctx, args);
    // 當事件真正執行後,清空定時器
    timer = null;
  };

  return function () {
    ctx = this;
    args = arguments;
    // 當持續觸發事件時,若發現事件觸發的定時器已設置時,則清除以前的定時器
    if (timer) {
      clearTimeout(timer);
      timer = null;
    }

    // 從新設置事件觸發的定時器
    timer = setTimeout(later, delay);
  };
}

效果圖:git

sample debounce

throttle 節流

throttle(節流),當持續觸發事件時,保證隔間時間觸發一次事件。github

throttle 節流

上圖中綠色塊表示觸發一次事件,持續觸發事件時,throttle會合並必定時間內的事件,並在該時間結束時真正去觸發一次事件~ 一塊兒來看看throttle的簡單實現:瀏覽器

function throttle(fn, delay) {
  var ctx;
  var args;
  // 記錄上次觸發事件
  var previous = Date.now();

  var later = function () {
    fn.apply(ctx, args);
  };

  return function () {
    ctx = this;
    args = arguments;
    var now = Date.now();
    // 本次事件觸發與上一次的時間比較
    var diff = now - previous - delay;

    // 若是隔間時間超過設定時間,即再次設置事件觸發的定時器
    if (diff >= 0) {
      // 更新最近事件觸發的時間
      previous = now;
      setTimeout(later, delay);
    }
  };
}

效果圖:閉包

sample throttle

總結

根據實際業務場景,合理的利用debounce(防抖)和throttle(節流)能夠優化性能和提升用戶體驗。二者間的核心區別就在於持續觸發事件時,前者合併事件並在最後時間去觸發事件,然後者則是隔間時間觸發一次~app

關鍵知識點

setTimeout 定時器less

w3school函數

Closure 閉包

ruanyifeng

資源

在線測試

源代碼

相關文章
相關標籤/搜索