GAP·MAP
← all breakdowns
JavaScriptEvent HandlingPerformancemiddle level

Debounce vs Throttle in UI Event Handlers

the question

What is the difference between debounce and throttle? Implement both in JavaScript, then explain which you would use for input, scroll, resize, and pointer movement.

what they're testing: The interviewer is probing whether you can control high-frequency work with closures and timers while choosing behavior that matches the interaction.

a strong answer

Debounce waits for calls to stop, then runs once with the latest arguments. Throttle keeps running during a burst, but no more than once per interval. Choose based on whether the UI needs a final result or progress.

A trailing debounce resets its timer on every call: function debounce(fn, wait) { let timer; return function (...args) { clearTimeout(timer); timer = setTimeout(() => fn.apply(this, args), wait); }; } The closure holds the timer; apply preserves context and arguments.

A leading throttle can also keep the latest blocked call for a trailing update: function throttle(fn, wait) { let blocked = false, pending; return function run(...args) { if (blocked) { pending = [this, args]; return; } fn.apply(this, args); blocked = true; setTimeout(() => { blocked = false; if (pending) { const [ctx, next] = pending; pending = undefined; run.apply(ctx, next); } }, wait); }; } That avoids losing the final state.

For search requests or validation, debounce the expensive work, not the visible input value. Throttle scroll or pointer work that must update during movement. Resize depends on the feature: debounce a final calculation or throttle a live preview. A timer delay is a minimum, not an exact execution time.

Why it lands

  • Separates quiet-period behavior from rate-limited progress.
  • Implements both utilities while preserving context and arguments.
  • Chooses by interaction needs instead of memorizing an event table.
  • Calls out leading, trailing, and timer timing semantics.

Where people slip

  • Saying both techniques merely delay a function.
  • Debouncing the visible input value and making typing feel laggy.
  • Assuming every throttle keeps the last blocked call, then relying on a trailing update that was never implemented.
  • Treating the timer delay as an exact execution time.

If they push further

How would you add cancellation or flushing?

Expose `cancel()` to clear stored timers and arguments, and `flush()` to run a pending trailing call immediately. Define what each method returns before coding it.

What changes if the debounced function starts a fetch?

Debouncing prevents some requests but does not cancel one already in flight. Use `AbortController` or ignore stale responses so an older result cannot overwrite a newer one.

Would you use requestAnimationFrame for scroll or pointer updates?

It is useful for grouping visual work with painting, but it is not a time-based throttle by itself. Store the latest position and keep the frame callback light.

Sources

Now answer it yourself.

Reading a strong answer is easy. Producing one under pressure is the skill the interview tests. Gapmap grades your answer against the same bar an interviewer would.

was this useful?

beta

The interviewer part is in the works.

The diagnostic, personal maps, and AI mock interviews are being finished right now. The notes stay free either way. Leave an email and you'll get the first-cohort invite, plus a month of Pro when it opens.