iT邦幫忙

2022 iThome 鐵人賽

DAY 19
0
自我挑戰組

菜鳥前端修練之旅系列 第 19

Day 19 | Debounce & Throttle

  • 分享至 

  • xImage
  •  

前端開發時常常會遇到事件頻繁執行的狀況:例如網頁滾動、模糊搜尋等,大量且頻繁觸發事件會非常浪費資源、且造成網頁非常卡。

該怎麼解決呢?來看看 Debounce & Throttle 這兩個東西。

Debounce(防抖)

Debounce 指的是 這個函式在某段期間內不論被觸發了多少次、都只會執行最後一次。

要怎麼定義 某個期間?我們會使用定時器 setTimeout 來完成。

以生活中坐公車的例子來看:我們規定司機在最後一位乘客上車後 5 秒後關門,如果 5 秒內又有新乘客上車,那麼重新計算 5 秒。

function debounce(fn, wait = 1000) {
  let timer = null;

  return function (...args) {
    if (timer) clearTimeout(timer);
    timer = setTimeout(() => {
      fn.apply(this, args);
    }, wait);
  };
}

上面的 wait 我們定義為 1000,所以持續在 1 秒內頻繁觸發的話,時間會持續往後延,直到最後一個事件為止。

可以在 scroll 事件中嘗試看看。

window.addEventListener("scroll", debounce(() => {
  console.log(window.scrollY);
}));

Throttle(節流)

Debounce 雖然好,但還有另一種情況:如果使用者長時間持續執行該事件、那這個事件就會遲遲無法執行。

所以我們使用 Throttle 來減緩事件觸發,只要計時器的時間一到、我們就執行該事件,程式碼則會記錄時間與上次做比較。

function throttle(func, time = 250) {
  let last;
  let timer;

  return function () {
    const context = this;
    const args = arguments;
    const now = +new Date();

    if (last && now < last + timeout) {
      clearTimeout(timer);
      timer = setTimeout(function () {
        last = now;
        func.apply(context, args);
      }, timeout);
    } else {
      last = now;
      func.apply(context, args);
    }
  };
}

以上就是簡易的 Debounce & Throttle 使用,學習之前可以先看一下 閉包this指向 的觀念,會更加理解程式碼。

另外如果要實作無限載入這種滾動效果的話,可以考慮使用 Intersection Observer 這個新的 Web API,使用上的效能會更好。

參考資料


上一篇
Day 18 | 表達式與陳述式
下一篇
Day 20 | IntersectionObserver
系列文
菜鳥前端修練之旅30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言