Debouncing
A programming practice used to ensure that time-consuming tasks do not fire so often that they stall the performance of a web page.
Detailed Explanation
Debouncing limits the rate at which a function can fire. For example, if a user is typing in a search box, you might debounce the API call so it only fires after the user has stopped typing for 300ms. This prevents hundreds of redundant network requests and keeps the UI responsive. It is a standard technique for performance optimization in interactive UIs.
Quick Summary
Debouncing delays running a function until a burst of events stops, the timer resets on every new event and only fires once the user pauses. It is the right tool when only the final value in a stream matters.
Key Takeaways
- Each new event cancels the pending timer and starts a fresh one, so rapid events produce exactly one delayed call.
- Typical wait times: 150–300 ms for keystrokes, 250–500 ms for window resize, 1 s+ for autosave.
- Leading-edge debounce fires immediately and ignores subsequent events; trailing-edge (the default) waits for the pause.
- Debounce is for "wait until they stop"; throttle is for "run at most every N ms." Picking the wrong one is the most common mistake.
- Always clean up timers on unmount or the callback can fire after the component is gone, causing memory leaks or React warnings.
When to use it
- Search-as-you-type inputs that hit a backend or run a fuzzy filter only after the user pauses.
- Autosaving editor content a fixed delay after the last keystroke.
- Validating form fields without flashing errors on every character.
- Resize handlers that recalculate layout once the window settles.
Common Mistakes
- Debouncing inside a render function so a new debounced function is created on every render, none of them ever fire together, defeating the purpose.
- Using debounce for scroll or mousemove where the user expects continuous response, throttle is the correct primitive.
- Forgetting to flush the pending call on form submit, so the last keystroke is lost.
- Setting the delay too high (>500 ms for keystrokes), which makes the UI feel laggy instead of efficient.
Debouncing, Frequently Asked
What is the difference between debounce and throttle?
Debounce waits until events stop and fires once; throttle fires at a fixed maximum rate while events continue. For a typing search, debounce. For a scroll-driven animation, throttle.
Should I write my own debounce or use a library?
Lodash and Underscore implementations handle leading/trailing edges, max-wait, and cancellation correctly. Hand-rolled debounces are fine for one-off cases but tend to leak the timer reference and miss cleanup.
Does debouncing work for promises and async functions?
Yes, but you have to handle stale results, a slow request started before the debounce can resolve after a fresh one. Track the latest call ID or use an AbortController to discard out-of-order responses.