DEV Community

Jaji
Jaji

Posted on

Debounce vs. Throttle: Explained with Simple Analogies

JavaScript's debounce and throttle functions are powerful tools for controlling how often a function executes, especially during rapid events like scrolling, resizing, or typing. Understanding when to use each can significantly improve your application's performance, but their differences can be confusing.

Let's use simple, real-world analogies to make these concepts crystal clear.

Debounce: The Waiting Photographer

Imagine you're trying to take a photo of an excited 5-year-old who can't stop jumping around.

With debounce, you're saying: "I'll only take the photo once the child has stopped moving for X seconds."

Here's how debounce works:

  1. Every time the child moves, you reset your timer
  2. The timer starts counting from zero again
  3. You only take the photo when the timer reaches X seconds without the child moving
  4. If the child never stops moving, you never take the photo
function debounce(func, wait) {
  let timeoutId = null;

  return function(...args) {
    // Clear any existing timeout
    if (timeoutId) {
      clearTimeout(timeoutId);
    }

    // Set new timeout
    timeoutId = setTimeout(() => {
      func.apply(this, args);
    }, wait);
  };
}
Enter fullscreen mode Exit fullscreen mode

Real-World Use Cases for Debounce:

  • Search input: Only search after the user stops typing for 500ms
  • Window resize: Only recalculate layout after the user finishes resizing
  • Form validation: Only validate after the user has finished making changes
  • Autocomplete: Only fetch suggestions after a brief pause in typing

Throttle: The Time-Limited Photographer

Now imagine you're at a playground where your 5-year-old is constantly doing cool tricks.

With throttle, you're saying: "I'll take at most one photo every X seconds, no matter how many cool things happen."

Here's how throttle works:

  1. You take the first photo immediately when requested
  2. You start a timer for X seconds
  3. During those X seconds, all photo requests are ignored
  4. After X seconds, the next photo request will be processed
  5. You'll get regular photos spaced at least X seconds apart
function throttle(func, wait) {
  let isThrottled = false;
  let savedArgs = null;
  let savedThis = null;

  function wrapper(...args) {
    // If we're in the throttle period
    if (isThrottled) {
      // Save latest arguments for later
      savedArgs = args;
      savedThis = this;
      return;
    }

    // Execute the function immediately
    func.apply(this, args);

    // Enter throttle period
    isThrottled = true;

    // After the wait period
    setTimeout(() => {
      isThrottled = false;

      // If we had additional calls during throttle
      if (savedArgs) {
        wrapper.apply(savedThis, savedArgs);
        savedArgs = null;
        savedThis = null;
      }
    }, wait);
  }

  return wrapper;
}
Enter fullscreen mode Exit fullscreen mode

Real-World Use Cases for Throttle:

  • Scroll events: Update UI at most every 100ms while scrolling
  • Game input: Process user actions at most 60 times per second
  • API polling: Check for updates at most once every 30 seconds
  • Mouse movement: Process mouse position at most every 50ms

Choosing Between Debounce and Throttle

Choose debounce when:

  • You want to wait for a "quiet period" before executing
  • The final state matters more than intermediate states
  • You want to batch rapid successive events into a single execution
  • You only care about the "settled" state

Choose throttle when:

  • You need to sample ongoing activity at regular intervals
  • You want real-time updates but need to limit their frequency
  • Progress matters, not just the final state
  • You want to ensure your function runs at a steady rate

Visual Comparison

Imagine a series of rapid events, like button clicks:

Events:     🖱️ 🖱️ 🖱️ 🖱️ 🖱️     🖱️ 🖱️ 🖱️ 🖱️     🖱️
           ┬─┬─┬─┬─┬─────┬─┬─┬─┬─────┬───────▶ time
           │ │ │ │ │     │ │ │ │     │
           │ │ │ │ │     │ │ │ │     │
Debounce:  │ │ │ │ │     │ │ │ │     ✓
           │ │ │ │ │     │ │ │ │     │
           │ │ │ │ │     │ │ │ │     │
Throttle:  ✓│ │ │ │   ✓  │ │ │ │   ✓ │
Enter fullscreen mode Exit fullscreen mode

Conclusion

Both debounce and throttle help you control the execution frequency of functions, but in different ways:

  • Debounce: Waits until activity stops before executing
  • Throttle: Executes at a regular interval during activity

By choosing the right technique, you can significantly improve your application's performance while providing a better user experience.

Top comments (0)