Skip to content
GeeksSmith
intermediate 5 min read

Debounce & Throttle Internals

Debounce delays execution until a burst of events pauses for N milliseconds; Throttle guarantees execution at most once every N milliseconds during continuous event streams.

Why it matters in interviews

Both techniques prevent event handler overloading on high-frequency DOM events (resize, scroll, keydown), protecting 60fps performance and preventing API rate-limit abuse.

Visual & Interactive Explanation

Debounce vs Throttle Execution Comparison

Interactive Comparison

Debounce

Execute after quiet period

Post-Inactivity
Trigger BehaviorResets timer on each call
Execution Count1 execution at the end of burst
Best Use CaseSearch typeahead, form autosave
Strengths
  • Minimizes network calls
  • Guarantees user stopped typing
Trade-offs
  • Delayed initial feedback if trailing only

Throttle

Execute at regular intervals

Capped Frequency
Trigger BehaviorCapped to 1 execution per interval
Execution CountRegular cadence during continuous action
Best Use CaseScroll listeners, window resizing, gaming
Strengths
  • Continuous responsive feedback
  • Predictable cadence
Trade-offs
  • May trigger more times than debounce

Code Examples & Implementation

Production TypeScript Debounce Implementation
function debounce<T extends (...args: any[]) => any>(
  fn: T,
  delay: number
): ((...args: Parameters<T>) => void) & { cancel: () => void } {
  let timer: ReturnType<typeof setTimeout> | null = null;

  const debounced = function (this: any, ...args: Parameters<T>) {
    if (timer) clearTimeout(timer);
    timer = setTimeout(() => {
      fn.apply(this, args);
      timer = null;
    }, delay);
  };

  debounced.cancel = () => {
    if (timer) {
      clearTimeout(timer);
      timer = null;
    }
  };

  return debounced;
}
Production Timestamp Throttle Implementation
function throttle<T extends (...args: any[]) => any>(
  fn: T,
  limit: number
): (...args: Parameters<T>) => void {
  let lastRan = 0;
  let timer: ReturnType<typeof setTimeout> | null = null;

  return function (this: any, ...args: Parameters<T>) {
    const now = Date.now();
    
    if (now - lastRan >= limit) {
      fn.apply(this, args);
      lastRan = now;
    } else {
      if (timer) clearTimeout(timer);
      timer = setTimeout(() => {
        fn.apply(this, args);
        lastRan = Date.now();
        timer = null;
      }, limit - (now - lastRan));
    }
  };
}

Interview-Ready Answers

Debounce resets a timer on every trigger and only runs after inactivity (e.g. search inputs). Throttle limits execution to a fixed periodic interval (e.g. infinite scroll, resize).

Official Documentation & Specifications

Follow-up Questions & Deep Dives

🎯 Code Output — What Does This Print?

Question 1medium
function debounce(fn, delay) {
  let timer;
  return function(...args) {
    clearTimeout(timer);
    timer = setTimeout(() => fn(...args), delay);
  };
}

const log = debounce(console.log, 100);
log("a");
log("b");
log("c");
// After 100ms, what is printed?
Question 2hard
function throttle(fn, limit) {
  let inThrottle = false;
  return function(...args) {
    if (!inThrottle) {
      fn(...args);
      inThrottle = true;
      setTimeout(() => inThrottle = false, limit);
    }
  };
}

const log = throttle(console.log, 1000);
log("a"); // t=0ms
log("b"); // t=50ms
log("c"); // t=100ms
// What is printed immediately?
Question 3tricky
let count = 0;
const inc = () => { count++; console.log(count); };

const debounced = (() => {
  let timer;
  return () => {
    clearTimeout(timer);
    timer = setTimeout(inc, 0);
  };
})();

debounced();
debounced();
debounced();
// After microtask+macrotask drain:

Common Mistakes & Anti-Patterns

  • Re-creating debounced functions inside React component bodies on every render without useMemo or useCallback
  • Failing to clean up timers on unmount, triggering state updates on unmounted components
  • Losing `this` context or arguments inside the timer callback

Real-World Architectural Scenario

In a React autosave editor, typing triggers a debounce save. But if the user suddenly navigates away, uncompleted edits are lost. How do you design this?

Rate Your Readiness

Rate how comfortably you can explain this in an interview to update your global readiness gauge:

Rate your confidence: