Performance Patterns

Back

Loading concept...

🎮 Events - Performance Patterns: Debouncing & Throttling

The Story of the Hyperactive Doorbell

Imagine you have a friend who loves pressing your doorbell. Not once. Not twice. But a hundred times in a row! 🔔🔔🔔

Every time they press it, you run to the door. You’re exhausted! Your legs hurt! And by the time you get there, they’re still pressing!

This is exactly what happens in JavaScript when users type, scroll, or resize windows. Your code runs way too many times.

But what if you could be smarter about this? What if you had two magical strategies?


🧙‍♂️ Meet Our Two Heroes

Hero Superpower
Debounce Waits until the chaos stops
Throttle Limits how often things happen

Think of them as traffic controllers for your JavaScript events!


🛑 Debouncing: “Wait Until They’re Done”

The Story

Remember that hyperactive doorbell friend?

Debouncing says: “I’ll wait. When they STOP pressing for 2 seconds, THEN I’ll answer.”

No more running to the door 100 times. You wait. They stop. You go once. Smart!

Real Life Examples

  • 🔍 Search box: Wait until user stops typing, THEN search
  • 📝 Auto-save: Wait until user stops writing, THEN save
  • 📱 Resize: Wait until window stops resizing, THEN recalculate

How It Works

graph TD A["User types 'H'"] --> B["Timer starts: 300ms"] B --> C["User types 'e'"] C --> D["Timer RESETS: 300ms"] D --> E["User types 'l'"] E --> F["Timer RESETS: 300ms"] F --> G["User stops typing"] G --> H["Timer completes!"] H --> I["🎉 Function runs ONCE"]

The Code

function debounce(func, delay) {
  let timer;

  return function(...args) {
    // Cancel previous timer
    clearTimeout(timer);

    // Start new timer
    timer = setTimeout(() => {
      func.apply(this, args);
    }, delay);
  };
}

Using Debounce

// Without debounce: runs 50 times!
input.addEventListener('input', search);

// With debounce: runs ONCE
const smartSearch = debounce(search, 300);
input.addEventListener('input', smartSearch);

🎯 Key Insight

Debouncing is like a patient waiter.

They don’t rush to take your order every time you say “umm…”

They wait until you’re DONE deciding. Then they write it down once.


⏱️ Throttling: “Only Once Every X Seconds”

The Story

Imagine a water faucet that can ONLY drip once per second. No matter how hard you turn it, one drip per second. That’s throttling!

Or think of a speed limit. Your car CAN go 200mph. But the limit is 60. You’re throttled.

Real Life Examples

  • 📜 Scroll events: Update position at most 10 times per second
  • 🎮 Game loop: Fire bullets at most once per second
  • 📊 Analytics: Send data at most once every 5 seconds

How It Works

graph TD A["Event fires"] --> B{Allowed to run?} B -->|Yes| C["Function runs"] C --> D["Lock for 100ms"] D --> E["Unlock"] B -->|No, locked| F["Ignored"] E --> G["Ready for next"]

The Code

function throttle(func, limit) {
  let inThrottle = false;

  return function(...args) {
    if (!inThrottle) {
      func.apply(this, args);
      inThrottle = true;

      setTimeout(() => {
        inThrottle = false;
      }, limit);
    }
  };
}

Using Throttle

// Without throttle: runs 100+ times!
window.addEventListener('scroll', updateNav);

// With throttle: runs every 100ms max
const smartNav = throttle(updateNav, 100);
window.addEventListener('scroll', smartNav);

🎯 Key Insight

Throttling is like a bouncer at a club.

“One person in every 10 seconds. I don’t care how long the line is!”


🤔 Debounce vs Throttle: When to Use What?

The Simple Rule

Situation Use This Why
User is typing Debounce Wait until they finish
User is scrolling Throttle Regular updates while scrolling
Window resizing Debounce Wait until resize ends
Button spam Throttle Allow one click per second
Search input Debounce Search when done typing
Game controls Throttle Limit action frequency

Visual Comparison

User Actions:  ||||||||||||||||||||| (many rapid events)

Debounce:      ___________________X (waits, fires ONCE at end)

Throttle:      X_____X_____X_____X_ (fires at regular intervals)

🌟 Real World Example: Search Box

Without Any Pattern (BAD)

searchInput.addEventListener('input', (e) => {
  // Runs on EVERY keystroke!
  fetch(`/search?q=${e.target.value}`)
    .then(res => res.json())
    .then(showResults);
});

// User types "pizza"
// 5 API calls: "p", "pi", "piz", "pizz", "pizza"
// Wastes bandwidth and server resources!

With Debounce (GOOD)

const debouncedSearch = debounce((query) => {
  fetch(`/search?q=${query}`)
    .then(res => res.json())
    .then(showResults);
}, 300);

searchInput.addEventListener('input', (e) => {
  debouncedSearch(e.target.value);
});

// User types "pizza"
// 1 API call: "pizza" (after 300ms pause)
// Efficient and smart!

🎨 Real World Example: Scroll Progress

Without Throttle (BAD)

window.addEventListener('scroll', () => {
  // Runs 100+ times per second!
  updateProgressBar();
  checkInfiniteScroll();
  updateNavHighlight();
});
// Browser becomes laggy and slow

With Throttle (GOOD)

const throttledScroll = throttle(() => {
  updateProgressBar();
  checkInfiniteScroll();
  updateNavHighlight();
}, 100);

window.addEventListener('scroll', throttledScroll);
// Smooth performance: only 10 updates per second

🏆 Quick Summary

Debounce

  • Waits until activity stops
  • Fires once after the quiet period
  • Best for: search, auto-save, resize

Throttle

  • Allows activity at regular intervals
  • Fires multiple times but limited
  • Best for: scroll, mouse move, game loops

💡 Pro Tips

  1. 300ms is a good debounce delay for typing
  2. 100ms is a good throttle limit for scroll
  3. Always clear timers when component unmounts
  4. These patterns save battery on mobile devices
  5. Use them to reduce API calls and server load

🎉 You Did It!

You now understand two of the most important performance patterns in JavaScript!

Debounce = “Calm down, wait until they’re done”

Throttle = “Slow down, only this often”

Use them wisely, and your apps will be fast, smooth, and efficient! 🚀

Loading story...

Story - Premium Content

Please sign in to view this story and start learning.

Upgrade to Premium to unlock full access to all stories.

Stay Tuned!

Story is coming soon.

Story Preview

Story - Premium Content

Please sign in to view this concept and start learning.

Upgrade to Premium to unlock full access to all content.