Debounce and Throttle Functions
In JavaScript, debounce and throttle are two commonly used techniques for optimizing high-frequency event handling. Both reduce the execution frequency of functions, thereby improving performance and avoiding unnecessary computations or requests. Below is a detailed explanation, implementation approach, and common usage scenarios encountered during development.
1. Debounce
“Debounce” means: when an event is triggered frequently, the callback function is executed only once after the event has stopped being triggered for a specified period.
In other words, if the event is triggered again within the set time interval, the timer is reset.
/**
* @param {function} fn - The function to be debounced
* @param {number} time - Delay in milliseconds before execution
* @param {boolean} flag - Whether to execute immediately on the first trigger
*/
function debounce(fn, time, flag) {
let timer;
return function(...args) {
// If triggered again within the 'time' window, clear the previous timer and restart
timer && clearTimeout(timer);
if (flag && !timer) {
// If 'flag' is true, execute immediately on the first call
fn.apply(this, args);
}
timer = setTimeout(() => {
fn.apply(this, args);
}, time);
};
}
Use Cases:
- Search input with auto-complete / suggestions
Sending a request on every keystroke is wasteful. Instead, wait 300ms after the user stops typing before sending the request. - Layout adjustment after window resize
If you only care about the final window size, use debouncing to avoid multiple reflows or repaints. - Form validation (e.g., email format check)
Avoid validating while the user is still typing; validate only after a pause. - Preventing duplicate form submissions on button click
Either disable the button temporarily or use debouncing to ensure submission happens only once.
2. Throttle
“Throttle” means: when an event is triggered frequently, the callback function is guaranteed to execute at least once every fixed time interval.
Even if the event keeps firing, the function will execute no more frequently than the specified minimum interval.
/**
* @param {function} fn - The function to be throttled
* @param {number} time - Minimum interval (in ms) between executions
* @param {boolean} flag - Whether to execute immediately on the first trigger
*/
function throttle(fn, time, flag) {
let timer;
return function(...args) {
// If 'flag' is true, execute immediately on the first call
if (flag) {
fn.apply(this, args);
// After the first execution, set 'flag' to false to prevent future immediate calls
flag = false;
}
if (!timer) {
timer = setTimeout(() => {
fn.apply(this, args);
clearTimeout(timer);
// Reset timer after execution
timer = null;
}, time);
}
};
}
Use Cases:
- Scroll event for infinite loading or scroll-based analytics
Instead of triggering on every pixel scrolled, execute once every 200ms. - Mouse movement tracking (e.g., drag-and-drop, drawing)
Limit processing frequency during continuousmousemoveevents. - Game mechanics like skill cooldowns or shooting rate control
Ensure abilities or actions cannot be spammed indefinitely. - Periodic data collection or heartbeat reporting
Control the reporting frequency to avoid excessive network requests.
3. Comparison Summary
| Feature | Debounce | Throttle |
|---|---|---|
| Trigger Timing | Executes after event stops (delayed) | Executes at fixed intervals during event stream |
| Immediate Execution | Configurable | Configurable |
| Best For | Scenarios where only the final result matters (e.g., search, form submit) | Scenarios requiring controlled frequency during ongoing events (e.g., scrolling, dragging) |
| Function Calls | Executes once after the last trigger | Executes multiple times, spaced by interval |