Performance Optimization

Debouncing vs
Throttling

Master the art of controlling function execution rates. Two powerful techniques to optimize event handling and create buttery-smooth user experiences.

10x
Performance Improvement
0ms
UI Blocking Prevention
Scalability Potential

Understanding the Concepts

Before diving into code, let's visualize how these techniques control function execution flow.

Debouncing

Delays function execution until after a specified wait time has elapsed since the last event. Think of it as a "smart delay" that resets the timer with every new event.

Event Timeline Wait: 300ms
Function executes only after user stops triggering events
Search Inputs Auto-save Resize End

Throttling

Ensures a function executes at most once per specified time interval, regardless of how many events fire. Like a "traffic controller" that maintains a steady execution rate.

Event Timeline Limit: 300ms
Function executes at regular intervals while events continue
Scroll Events Infinite Scroll Mouse Move

Interactive Playground

Move your mouse over the areas below to see the difference in real-time

Normal

No Control
Events: 0 Executions: 0
Every mouse move triggers function execution immediately
Recommended

Debounce

300ms
Events: 0 Executions: 0
Executes only after you stop moving for 300ms

Throttle

300ms
Events: 0 Executions: 0
Executes maximum once every 300ms while moving

Search Input Simulation

Type in the search box below to see how debouncing prevents excessive API calls while typing.

0
Normal API Calls
0
Debounced Calls
console.log
// Start typing to see logs...

Implementation

Clean, production-ready code implementations

Debounce Function

Leading & Trailing edge support

function debounce(func, wait, immediate = false) {
  let timeout;
  
  return function executedFunction(...args) {
    const later = () => {
      timeout = null;
      if (!immediate) func.apply(this, args);
    };
    
    const callNow = immediate && !timeout;
    clearTimeout(timeout);
    timeout = setTimeout(later, wait);
    
    if (callNow) func.apply(this, args);
  };
}

// Usage
const handleSearch = debounce((query) => {
  console.log('Searching for:', query);
  // API call here
}, 300);

input.addEventListener('input', (e) => handleSearch(e.target.value));

Throttle Function

With trailing execution option

function throttle(func, limit, trailing = true) {
  let inThrottle;
  let lastFunc;
  let lastRan;
  
  return function executedFunction(...args) {
    const context = this;
    
    if (!inThrottle) {
      func.apply(context, args);
      lastRan = Date.now();
      inThrottle = true;
      
      setTimeout(() => {
        inThrottle = false;
        if (trailing && lastFunc) {
          lastFunc.apply(context, args);
          lastFunc = null;
        }
      }, limit);
    } else if (trailing) {
      lastFunc = () => func.apply(context, args);
    }
  };
}

// Usage
const handleScroll = throttle(() => {
  console.log('Scroll position:', window.scrollY);
}, 100);

window.addEventListener('scroll', handleScroll);

When to Use What

Scenario Technique Reason
Search Input Debounce Wait for user to finish typing
Window Resize Debounce Recalculate layout after resize ends
Infinite Scroll Throttle Check scroll position at intervals
Button Clicks Debounce Prevent double submission
Mouse Move Throttle Update coordinates smoothly
Copied to clipboard!