Type 5 keys, send 1 request: how a 300ms debounce works
TL;DR
Debounce delays a function call until there’s a long enough pause. Each keystroke cancels the pending timer and restarts it, so typing “redis” produces exactly one request instead of five.
Without vs. with debounce
| No debounce | 300ms debounce | |
|---|---|---|
| Typing “redis” | 5 requests: r, re, red, redi, redis | 1 request: redis |
| 220ms pause after “red” | Request still fires | Under 300ms → cancelled when “i” is typed |
| Server load | Processes half-typed queries | Only the final query |
Minimal implementation
function debounce(fn, ms = 300) {
let t;
return (...args) => {
clearTimeout(t);
t = setTimeout(() => fn(...args), ms);
};
}
input.addEventListener('input', debounce(e => search(e.target.value)));How to put it to work
- Use debounce for search boxes, autosave, validate-as-you-type and resize events.
- Use throttle instead when you need steady updates while the user is still acting (scrolling, dragging).
- Combine with
AbortControllerto cancel stale requests so late responses don’t overwrite newer results.