DEV Community

Ashish Ghildiyal
Ashish Ghildiyal

Posted on

Throttling in JavaScript

🧠 What is Throttling in JavaScript?

In JavaScript, throttling is a technique to:

Limit how often a function can execute within a given time interval

🎯 One-Line Difference from Debounce

Debounce β†’ run after user stops
Throttle β†’ run at most once every X ms

⚑ Problem Throttling Solves

Some events fire continuously:

scroll
resize
mousemove

πŸ‘‰ Without control:

Scroll β†’ function fires 100+ times/sec ❌

πŸ‘‰ With throttling:

Scroll β†’ function fires every 200ms βœ…

πŸ”¬ Core Idea

β€œAllow execution only once per time window”

🧩 Step-by-Step Example

Scenario: Throttle with 1000ms (1 second)

User scrolls continuously.

Timeline

Time:   0ms   200ms   400ms   600ms   800ms   1000ms

Events:  βœ”     βœ”       βœ”       βœ”       βœ”       βœ”
Run:     βœ…     ❌      ❌      ❌      ❌      βœ…

Enter fullscreen mode Exit fullscreen mode

πŸ‘‰ Only first and after 1s β†’ execution happens

βš™οΈ How It Works Internally

Key idea:
Track last execution time
Ignore calls until delay passes

πŸ’» Basic Throttle Implementation

javascript


function throttle(fn, delay) {
  let lastCall = 0;

  return function (...args) {
    const now = Date.now();

    if (now - lastCall >= delay) {
      lastCall = now;
      fn.apply(this, args);
    }
  };
}
Enter fullscreen mode Exit fullscreen mode

πŸ” Step-by-Step Internal Flow

  1. First call

lastCall = 0
now = 1000

β†’ execute function
β†’ lastCall = 1000

  1. Next call (within delay) now = 1200

1200 - 1000 = 200 < 1000 ❌
β†’ ignore

  1. After delay now = 2000

2000 - 1000 = 1000 βœ…
β†’ execute again

🧠 Visual Flow

Event β†’ Check time β†’ Execute or Ignore

βš™οΈ Alternative Implementation (Timer-Based)

function throttle(fn, delay) {
  let timer = null;

  return function (...args) {
    if (!timer) {
      fn.apply(this, args);

      timer = setTimeout(() => {
        timer = null;
      }, delay);
    }
  };
}
Enter fullscreen mode Exit fullscreen mode

πŸ” How This Version Works

First call β†’ executes immediately
Sets a lock (timer)
Ignores calls until timer resets

⚑ Real-World Example
Scroll Handler

window.addEventListener(
  "scroll",
  throttle(() => {
    console.log("Scroll handled");
  }, 200)
);
Enter fullscreen mode Exit fullscreen mode

πŸ‘‰ Instead of 100+ calls/sec β†’ controlled calls

🧠 Use Cases

βœ… Best for:
Scroll tracking
Window resize
Mouse movement
Button spam prevention

βš–οΈ Throttle vs Debounce (Deep Comparison)

πŸ”₯ Advanced Throttle (Leading + Trailing)


function throttle(fn, delay, options = { leading: true, trailing: true }) {
  let lastCall = 0;
  let timer;

  return function (...args) {
    const now = Date.now();

    if (!lastCall && options.leading === false) {
      lastCall = now;
    }

    const remaining = delay - (now - lastCall);

    if (remaining <= 0) {
      clearTimeout(timer);
      lastCall = now;
      fn.apply(this, args);
    } else if (!timer && options.trailing !== false) {
      timer = setTimeout(() => {
        lastCall = Date.now();
        timer = null;
        fn.apply(this, args);
      }, remaining);
    }
  };
}
Enter fullscreen mode Exit fullscreen mode

🧠 Leading vs Trailing

⚠️ Common Mistakes

❌ Using debounce instead of throttle (wrong use case)
Scroll β†’ use throttle
Input β†’ use debounce

❌ Losing this context
Use:
fn.apply(this, args)

🧭 Mental Model

Throttle = β€œRun at fixed intervals, no matter how many events happen”

🎯 Final Takeaway

  • Throttling controls execution frequency
  • Ensures consistent performance
  • Critical for UI-heavy applications

Top comments (0)