🚀 LEVEL UP TO SENIOR:Unlock 500+ Advanced Practical Challenges & Exercises.
🎓 COURSERA PARTNER:Earn professional Google, Meta, and IBM certificates to supercharge your resume.
JS MASTER CLASS /// MASTER THE ENGINE /// BUILD LOGIC /// ASYNC PATTERNS /// JS MASTER CLASS /// MASTER THE ENGINE ///

Throttle | JavaScript Tutorial - In-Depth Guide

Master throttling: implementing a throttle utility, how it differs fundamentally from debounce, leading vs trailing invocation choices, and real-world scroll/resize use cases.

Total XP: 0|💻 javascript XP: 0

Skill Matrix

UNLOCK NODES BY LEARNING NEW TAGS.

System Hub

Core logic.

Quick Quiz //

During 5 seconds of continuous, rapid activity, does a throttled function fire multiple times, or just once at the end?


🚀 LEVEL UP TO SENIOR:Unlock 500+ Advanced Practical Challenges & Exercises.
🎓 COURSERA PARTNER:Earn professional Google, Meta, and IBM certificates to supercharge your resume.

Throttling guarantees a function runs at most once per fixed time interval, no matter how often it's triggered — the standard tool for scroll handlers, mouse-move tracking, and any continuously-firing event that needs a steady, capped execution rate.

1Throttle | JavaScript Tutorial - In-Depth Guide Part 1

Throttling ensures a function executes at most once every fixed interval, regardless of how many times it's actually called during that window.

+
function throttle(fn, interval) {
  let lastCall = 0;
  return (...args) => {
    const now = Date.now();
    if (now - lastCall >= interval) {
      lastCall = now;
      fn(...args);
    }
  };
}
localhost:3000
🚦

Limiting Call Frequency

2Throttle | JavaScript Tutorial - In-Depth Guide Part 2

The fundamental difference from debounce: throttle guarantees the function runs periodically DURING continuous activity, while debounce only runs it once AFTER activity stops.

+
// Throttle: fires repeatedly during continuous scrolling
// Debounce: fires once, after scrolling stops
localhost:3000

Throttle vs Debounce

3Throttle | JavaScript Tutorial - In-Depth Guide Part 3

A basic throttle implementation (timestamp comparison) only fires on the leading edge of each interval — a final call right at the end of a burst might be dropped if it doesn't land exactly on an interval boundary.

+
function throttleWithTrailing(fn, interval) {
  let lastCall = 0, timeoutId;
  return (...args) => {
    const now = Date.now();
    const remaining = interval - (now - lastCall);
    if (remaining <= 0) {
      lastCall = now;
      fn(...args);
    } else {
      clearTimeout(timeoutId);
      timeoutId = setTimeout(() => { lastCall = Date.now(); fn(...args); }, remaining);
    }
  };
}
localhost:3000

Ensuring the Last Call Fires

4Throttle | JavaScript Tutorial - In-Depth Guide Part 4

Throttling a scroll or mousemove handler prevents expensive layout calculations from running on every single fired event, which can number in the hundreds per second.

+
window.addEventListener('scroll', throttle(() => {
  updateStickyHeaderPosition();
}, 100));
localhost:3000

Throttling Scroll Handlers

5Throttle | JavaScript Tutorial - In-Depth Guide Part 5

For animations tied to scroll or resize, requestAnimationFrame is often an even better fit than a fixed-interval throttle, since it naturally syncs to the browser's actual repaint rate.

+
let ticking = false;
window.addEventListener('scroll', () => {
  if (!ticking) {
    requestAnimationFrame(() => {
      updateParallaxEffect();
      ticking = false;
    });
    ticking = true;
  }
});
localhost:3000

requestAnimationFrame Throttling

6Step-by-Step Breakdown

Throttling ensures a function executes at most once every fixed interval, regardless of how many times it's actually called during that window.

The fundamental difference from debounce: throttle guarantees the function runs periodically DURING continuous activity, while debounce only runs it once AFTER activity stops.

Checkpoint: During 5 seconds of continuous, rapid activity, does a throttled function fire multiple times, or just once at the end?

  • Multiple times, spaced roughly by the interval
  • Just once, after the activity stops

A basic throttle implementation (timestamp comparison) only fires on the leading edge of each interval — a final call right at the end of a burst might be dropped if it doesn't land exactly on an interval boundary.

Throttling a scroll or mousemove handler prevents expensive layout calculations from running on every single fired event, which can number in the hundreds per second.

Checkpoint: Is throttling a scroll handler a common technique to prevent performance jank?

  • Yes, scroll events can fire far more often than needed
  • No, scroll events already fire at a safe, limited rate natively

For animations tied to scroll or resize, requestAnimationFrame is often an even better fit than a fixed-interval throttle, since it naturally syncs to the browser's actual repaint rate.

Next, we'll explore 'requestAnimationFrame'.

Level Up 🚀

Advanced cheat sheets, SEO tricks, and interview prep for this topic.

Browser Support

ChromeSupported

Fully supported.

FirefoxSupported

Fully supported.

SafariSupported

Fully supported.

EdgeSupported

Fully supported.

Accessibility (A11y)

1Throttle Scroll-Triggered Focus or Announcement Changes to Avoid Overwhelming Screen Readers

If scroll position drives dynamic ARIA live region updates (like a 'reading progress' announcement), throttle those updates significantly (much slower than a visual scroll indicator) to avoid firing rapid, overlapping announcements that overwhelm screen reader users.

SEO Implications

  • 1

    Throttled Scroll Handlers Improve Scroll Responsiveness Metrics

    Reducing the computational load of scroll event handlers via throttling helps maintain smooth scrolling and responsiveness, contributing positively to Interaction to Next Paint and overall perceived performance.

Best Practices

Throttle Continuously-Firing Events Like Scroll and Mousemove

These events can fire far more often than any handler realistically needs to respond to, and throttling caps the execution rate to something the main thread can comfortably keep up with.

Consider requestAnimationFrame Instead of a Fixed Interval for Visual Updates

It naturally throttles to the display's actual refresh rate and avoids wasted work computing visual updates faster than the screen can render them.

Frequent Bugs

THE BUG

Using debounce instead of throttle for a scroll-position indicator, causing it to update only once scrolling stops, instead of continuously as the user scrolls.

THE FIX

Use throttle when you need periodic updates during continuous activity; reserve debounce for cases where only the final state after activity stops matters.

THE BUG

Using a basic leading-edge-only throttle for a progress indicator, causing the very last update (e.g. reaching 100%) to sometimes never render if it falls within an unfired interval window.

THE FIX

Use a throttle implementation that also guarantees a trailing-edge call, ensuring the final state is never dropped.

Real-World Examples

Throttling a Sticky Header Show/Hide Effect

A page needed to hide a sticky header when scrolling down and show it when scrolling up, without recalculating scroll direction on every single fired scroll event.

let lastScrollY = 0;
window.addEventListener('scroll', throttle(() => {
  const direction = window.scrollY > lastScrollY ? 'down' : 'up';
  header.classList.toggle('hidden', direction === 'down');
  lastScrollY = window.scrollY;
}, 150));

Interview Prep

?Frequently Asked Questions

Pascual Vila

Pascual Vila

Frontend Instructor // Code Syllabus

Common Pitfalls & Errors

The Error //

Using debounce where throttle was actually needed (continuous updates)

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

The Solution //

Switch to throttle when periodic execution during ongoing activity is required, not just a single final call.

Lesson Glossary

[01]Throttle

Guaranteeing a function executes at most once per fixed time interval.

Code Preview
throttle(fn, 100)

[02]Leading-Edge Throttle

A throttle that fires immediately at the start of each interval window.

Code Preview
fires at window start

[03]Trailing-Edge Call

An extra call scheduled to ensure the final update in a burst is not dropped by a leading-edge-only throttle.

Code Preview
setTimeout(remaining)

[04]requestAnimationFrame Throttling

Syncing a handler's execution rate to the browser's repaint cycle instead of a fixed time interval.

Code Preview
requestAnimationFrame(fn)

[05]Forced Reflow

An expensive synchronous layout recalculation triggered by reading certain DOM properties, worth minimizing in frequent handlers.

Code Preview
el.offsetHeight

Continue Learning