Debounce and Throttle in JavaScript

A
Author
10 May, 2026 1 min read 1.38K views

Some events fire very often: typing, scrolling, resizing. Running expensive work (an API call, a layout calculation) on every event wastes resources and can make the page janky.

Debounce: wait until things calm down

Run the function only after the events have stopped for a given time. Perfect for search-as-you-type and autosave.

function debounce(fn, wait = 300) {
  let timer;
  return function (...args) {
    clearTimeout(timer);
    timer = setTimeout(() => fn.apply(this, args), wait);
  };
}

const search = debounce(async (query) => {
  const res = await fetch(`/api/search?q=${encodeURIComponent(query)}`);
  renderResults(await res.json());
}, 300);

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

Throttle: at most once per interval

Run the function at a steady maximum rate while events keep coming. Good for scroll position tracking and drag handlers.

function throttle(fn, interval = 100) {
  let last = 0;
  let timer;
  return function (...args) {
    const now = Date.now();
    const remaining = interval - (now - last);
    clearTimeout(timer);
    if (remaining <= 0) {
      last = now;
      fn.apply(this, args);
    } else {
      // make sure the final call still happens
      timer = setTimeout(() => {
        last = Date.now();
        fn.apply(this, args);
      }, remaining);
    }
  };
}

window.addEventListener('scroll', throttle(updateProgressBar, 100));

Which one?

  • Debounce: you only care about the final value (search, validation, autosave, window resize end).
  • Throttle: you need regular updates during the activity (scroll, mousemove, game input).

In React

const debouncedSave = useMemo(() => debounce(saveDraft, 1000), []);
useEffect(() => () => debouncedSave.cancel?.(), [debouncedSave]);

For visual updates tied to scrolling, requestAnimationFrame is often better than a time-based throttle, and for "is this element visible", use IntersectionObserver instead of scroll events altogether.

Was this article helpful?

Comments

No comments yet. Have a question or a tip? Be the first to share it.

Leave a comment

Comments are reviewed before they appear.