iT邦幫忙

2026 iThome 鐵人賽

DAY 24
0
Software Development

文科生的軟體工程啟蒙:用一個代購 App,看懂 30 個系統設計觀念系列 第 24 篇

Day 24:防抖(Debounce)與節流(Throttle)——高頻事件下的效能防護機制

  • 分享至 

  • xImage
  •  

昨天談的是演算法本身的時間複雜度,但前端效能問題還有另一個常見來源:使用者操作觸發事件的「頻率」。打字、捲動、拖曳視窗,這些動作短短一秒內可能觸發幾十次事件,如果每一次都執行一次完整的運算或 API 呼叫,再快的演算法也會被拖垮。今天要談的防抖與節流,就是控制「事件觸發頻率」的兩種機制。

一、防抖(Debounce)

定義:在事件停止觸發「一段時間」之後,才真正執行對應的函式;如果在這段等待時間內事件又被觸發,就重新計時。效果是:只有當使用者真的停下來之後,函式才會被執行一次。

二、節流(Throttle)

定義:規定函式在「固定時間間隔」內最多只能執行一次,不管事件在這段時間內觸發了多少次。效果是:函式會以穩定的頻率持續被執行,而不是完全等到使用者停下來。

三、兩者的差異與使用時機

Debounce 適合「只關心使用者『最終』的那個狀態」的場景,例如打字搜尋——使用者還在打字時不需要查詢,等他打完才查一次。Throttle 則適合「過程中也需要持續反應」的場景,例如捲動視窗時持續載入更多內容——不需要每一個捲動事件都觸發,但也不能等到使用者完全停止捲動才反應。

四、代購 App 案例

商品搜尋框很適合用 Debounce:使用者每打一個字都呼叫一次 API 查詢,既浪費後端資源,也容易因為回應順序不一致而顯示錯誤的結果。

// utils/debounce.js
function debounce(fn, delay) {
  let timer;
  return (...args) => {
    clearTimeout(timer); // 事件再次觸發,重新計時
    timer = setTimeout(() => fn(...args), delay);
  };
}

// 商品搜尋框:使用者停止打字 300ms 後,才真正呼叫搜尋 API
const handleSearch = debounce((keyword) => {
  searchProducts(keyword); // 呼叫 API
}, 300);
searchInput.addEventListener('input', (e) => handleSearch(e.target.value));

商品列表捲動載入更多資料,則適合用 Throttle:即使使用者持續快速捲動,也只需要每隔一段固定時間檢查一次是否該載入下一頁,不需要每一個 scroll 事件都檢查。

// utils/throttle.js
function throttle(fn, interval) {
  let lastTime = 0;
  return (...args) => {
    const now = Date.now();
    if (now - lastTime >= interval) { // 固定時間間隔內最多執行一次
      lastTime = now;
      fn(...args);
    }
  };
}

// 商品列表捲動:每 200ms 最多檢查一次是否捲到底部,需要載入下一頁
const handleScroll = throttle(() => {
  if (isNearBottom()) loadMoreProducts();
}, 200);
window.addEventListener('scroll', handleScroll);

五、結論

防抖讓函式「等使用者停下來才執行一次」,節流讓函式「以固定頻率持續執行」——兩者都是在不改變功能本身的前提下,控制事件被處理的頻率,跟 Day 23 談的演算法複雜度是兩個不同層次的效能問題:一個管「每次執行要花多少運算」,一個管「要執行幾次」,實務上常常需要同時處理。


上一篇
Day 23:效能瓶頸分析——時間複雜度(Big-O)在前端資料過濾與渲染中的實際體現
下一篇
Day 25:模組打包與依賴管理——從單一腳本到模組建置工具(Bundler)的演進邏輯
系列文
文科生的軟體工程啟蒙:用一個代購 App,看懂 30 個系統設計觀念 共 26 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言