FE Interview Hub
Web VitalsIntermediate

What is throttle? How do you implement a throttle function?

AI Practice

What is Throttle?

Throttle limits a function so it runs at most once every N milliseconds. No matter how often the event fires in that interval, the function executes only once.

Idea: run on a fixed rhythm.

Common use cases

  • scroll (infinite scroll, parallax, "back to top" visibility)
  • mousemove (drag, mouse tracking)
  • Game shooting / attack cooldowns
  • Window resize when you want a live-but-rate-limited response

Implementation 1: timestamp version (leading)

Runs on the first call, then at most once every delay ms.

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

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

    if (now - lastTime >= delay) {
      fn.apply(this, args);
      lastTime = now;
    }
  };
}

Implementation 2: timer version (trailing)

Skips the first call and executes after delay. After that, starts a new cycle.

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

  return function (...args) {
    if (timer) return;

    timer = setTimeout(() => {
      fn.apply(this, args);
      timer = null;
    }, delay);
  };
}

Implementation 3: leading + trailing

Combine both approaches — fire immediately on the first call and also after the final call.

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

  return function (...args) {
    const now = Date.now();
    const remaining = delay - (now - lastTime);

    if (remaining <= 0) {
      // Time's up — invoke immediately
      if (timer) {
        clearTimeout(timer);
        timer = null;
      }
      lastTime = now;
      fn.apply(this, args);
    } else if (!timer) {
      // Schedule the trailing call
      timer = setTimeout(() => {
        lastTime = Date.now();
        timer = null;
        fn.apply(this, args);
      }, remaining);
    }
  };
}

Usage

const onScroll = throttle(() => {
  console.log('scrollY:', window.scrollY);
}, 200);

window.addEventListener('scroll', onScroll);

Implementation notes

  • Timestamp version: fires on the first call, but may drop the last one.
  • Timer version: guarantees a trailing call, but delays the first.
  • Combined version: matches lodash _.throttle behaviour.
  • Remember to use fn.apply(this, args) to preserve the caller's context.

Throttle vs Debounce

Throttle Debounce
Strategy Fixed rate Only after things stop
Analogy Faucet dripping at a fixed rate Elevator waiting for the last person
Best for scroll, mousemove, cooldowns Search, resize, validation

✦ AI Mock Interview

Type your answer and get instant AI feedback

Sign in to use AI scoring