A search box fires an event on every keystroke; scroll fires hundreds of times a second. Sending an API call for each would melt your server. Two patterns fix this โ and both are common interview asks.
Debounce โ wait for silence
Run only after the user stops for N ms. Perfect for search inputs, resize handlers, autosave.
function debounce(fn, delay = 400) {
let timer;
return (...args) => {
clearTimeout(timer);
timer = setTimeout(() => fn(...args), delay);
};
}
input.addEventListener("input", debounce(e => search(e.target.value)));Throttle โ at most once per interval
Run at a steady maximum rate. Perfect for scroll position, mousemove, game loops.
function throttle(fn, limit = 200) {
let waiting = false;
return (...args) => {
if (waiting) return;
fn(...args);
waiting = true;
setTimeout(() => waiting = false, limit);
};
}
window.addEventListener("scroll", throttle(updateProgressBar));One-line memory trick
Debounce = after the burst ends. Throttle = during the burst, at a fixed rate. Note both use closures โ two interview topics in one.