Debounce vs Throttle: Two Event Control Techniques Every Developer Needs

Events like scroll, window resize, and input can fire handlers hundreds of times per second. Left unchecked, the CPU gets hammered and the UI stutters. Debounce and Throttle solve this — but they work in completely different ways.

debouncethrottletối ưu hiệu năngJavaScript
Cover image: Debounce vs Throttle: Two Event Control Techniques Every Developer Needs
Avatar of Trung Vũ Hoàng

Trung Vũ Hoàng

Author

30/3/20264 min read

1. Debounce — "Wait until it's over, then act"

Debounce forces a function to wait a specified amount of time after the last trigger before executing. If the event fires again during the wait, the countdown resets to 0.

Think of an automatic elevator: it doesn’t close the doors the moment you step in. It waits 5 seconds — if someone else steps in at second 3, it waits another 5 seconds. It only closes when no one steps in for 5 consecutive seconds.

function debounce(func, delay) {
  let timeoutId;
  return function(...args) {
    clearTimeout(timeoutId);
    timeoutId = setTimeout(() => {
      func.apply(this, args);
    }, delay);
  };
}

// Only call the API after the user stops typing for 500ms
const searchHandler = debounce(() => fetchResults(query), 500);

2. Throttle — "Keep a steady pace"

Throttle ensures a function executes at most once within a fixed time window — no matter how many times the event fires during that window.

Like a scheduled bus: it departs every 15 minutes. Whether 1 or 100 people are waiting, it still leaves on the set cadence.

function throttle(func, limit) {
  let lastRan;
  return function(...args) {
    if (!lastRan) {
      func.apply(this, args);
      lastRan = Date.now();
    } else if (Date.now() - lastRan >= limit) {
      func.apply(this, args);
      lastRan = Date.now();
    }
  };
}

// Check scroll position at most once per second
const scrollHandler = throttle(() => checkScrollPosition(), 1000);

3. Side-by-Side Comparison

Execution timing

  • Debounce: After the event pauses (trailing edge).

  • Throttle: At a steady cadence while the event is happening.

Call frequency

  • Debounce: Might be called only once even if the user keeps interacting for several seconds.

  • Throttle: Calls multiple times at a steady cadence based on the total duration and the interval.

UX goal

  • Debounce: Accurate results after the interaction is complete.

  • Throttle: Continuous feedback, but within controlled limits.

4. When Should You Use Each?

Choose Debounce when:

  • Search autocomplete: Wait for the user to stop typing before calling the API — avoiding dozens of unnecessary requests.

  • Real-time form validation: Check whether an email already exists after the user finishes typing, not on every keystroke.

  • Window resize: Recalculate layout only after the user finishes resizing the window.

Choose Throttle when:

  • Infinite scroll: Check whether the user is near the bottom — every 100–200ms is sufficient.

  • Mouse tracking / Canvas drawing: Track mouse coordinates for drawing or effects with continuous but limited updates.

  • Prevent Submit button spam: Users may click repeatedly — only process at the defined cadence.

Using the wrong technique = bad UX: Using Debounce for mouse tracking makes brush strokes on a canvas appear only when the user stops moving — the app looks completely frozen.

5. Notes When Using in React

When using Debounce/Throttle in a React component, wrap the function with useCallback to avoid recreating it on every render — that would reset the timer and break the logic:

const debouncedSearch = useCallback(
  debounce((query) => fetchResults(query), 500),
  [] // Create the debounced function only once
);

In production, prefer _.debounce and _.throttle from Lodash — they handle tricky edge cases (leading/trailing edges, cancellation, etc.) that homegrown implementations often miss.

Wrap-up

Debounce and Throttle are fundamentals in every web developer’s toolkit. Quick rules of thumb:

  • Debounce → "Act only when the user stops."

  • Throttle → "Act at a steady rate even if the user doesn’t stop."

Audit your application — which events are wasting resources unnecessarily? That’s exactly where these two techniques shine.

Frequently Asked Questions

Share this article
Zalo

Found this article helpful?

Contact us for a free consultation about our services

Contact us

Bài viết liên quan