前端效能之防抖與節流
前言
遙想當年,第一次接觸防抖(debounce)與節流(throttle)時,想說這又是什麼奇怪的術語,為啥要把事情搞得那麼複雜?之後做一下簡單的搜尋,知道是用來提升效能、防止stack overflow的解決方案,而後就是遇到相似的feature、直接用lodash.debounce來應付應付。
不過,最近在翻修新公司的舊專案,發現很多地方都沒有利用debounce/throttle來優化,用著用著突然覺得自己對於兩者的分別其實也沒有到非常清楚,因此本篇文算是用來自我梳理一下,兩者的作用以及常見的使用場景。
throttle(節流)
官方說法是,throttle是讓一個函數在一段時間內只執行一次,而且它是連續執行的。常見的使用場景為 視窗scroll、視窗resize等連續事件,主要是避免 scroll/resize頻繁觸發而導致stack overflow
throttle demo:
funtion throttle( targetFunc, limitPeriod ){
let inThrottle;
return function()=>{
const args = arguments;
const context = this;
if (!isThrottle) {
targetFunc.apply(context, args);
inThrottle = true;
setTimeout(() => inThrottle = false, limit);
}
}
}
throttle demo with arrow function
funtion throttle( targetFunc, limitPeriod ){
let inThrottle;
return (...args)=>{
if (!inThrottle) {
targetFunc(...args);
inThrottle = true;
setTimeout(() => inThrottle = false, limit);
}
}
}
Debounce(防抖)
對於debounce來說,它是在一段時間之後才執行該函數,目的是為了獲取最後一次觸發的事件。常見的使用場景為 input來執行函數、提交表單,而視窗的 scroll/resize時機也可以用debounce,不過目的是為了在 scroll/resize 停止一段時間後再執行目標事件。
debounce demo
function debounce( targetFunc, delayPeriod ){
let inDebounce;
return function(){
const args = arguments;
const context = this;
clearTimeout(inDebounce);
inDebounce = setTimeout(() => targetFunc.apply(context, args), delayPeriod);
}
}
debounce demo with arrow function
function debounce( targetFunc, delayPeriod ){
let inDebounce;
return (...args)=>{
clearTimeout(inDebounce);
inDebounce = setTimeout(() => targetFunc( ...args), delayPeriod);
}
}
Ref
- lodash document: link
ChangeLog
- 20230627: 初稿