What is Throttle
Throttling limits how often a function can execute. It ensures a function is called at most once every X milliseconds, regardless of how many times it's triggered.
The Problem
// Without throttle - fires continuously during scroll
window.addEventListener('scroll', () => {
updateScrollIndicator(); // Runs hundreds of times per second!
});
The Solution
// With throttle - runs at most once every 200ms
const throttledUpdate = throttle(updateScrollIndicator, 200);
window.addEventListener('scroll', throttledUpdate);
Analogy
Imagine a water tap with a flow limiter. No matter how hard you turn the handle, water only flows at a set rate.
Scroll events: ||||||||||||||||||||||||||||||||| (continuous)
Throttled: |---200ms---|---200ms---|---200ms---| (limited)
Debounce vs Throttle
| Feature | Debounce | Throttle |
|---|---|---|
| When it fires | After pause in calls | At fixed intervals |
| Frequency | Once after last call | Regular intervals |
| Use case | Search input | Scroll, resize |
Common Use Cases
- Scroll events (update position at fixed rate)
- Mouse move tracking (limit mousemove events)
- Button clicks (prevent rapid clicks)
- Game loops (limit frame rate)
Implementation
Here's how to implement a throttle function from scratch.
Basic Implementation
function throttle(func, limit) {
let inThrottle = false;
return function(...args) {
if (!inThrottle) {
func.apply(this, args);
inThrottle = true;
setTimeout(() => {
inThrottle = false;
}, limit);
}
};
}
Usage
function handleScroll() {
console.log('Scroll position:', window.scrollY);
}
const throttledScroll = throttle(handleScroll, 100);
window.addEventListener('scroll', throttledScroll);
Leading + Trailing Implementation
Executes on first call AND at the end of the interval.
function throttle(func, limit) {
let inThrottle = false;
let lastArgs = null;
return function(...args) {
if (!inThrottle) {
func.apply(this, args);
inThrottle = true;
setTimeout(() => {
inThrottle = false;
if (lastArgs) {
func.apply(this, lastArgs);
lastArgs = null;
}
}, limit);
} else {
lastArgs = args; // Store for trailing execution
}
};
}
Timestamp-Based Implementation
More accurate timing using timestamps.
function throttle(func, limit) {
let lastCall = 0;
return function(...args) {
const now = Date.now();
if (now - lastCall >= limit) {
lastCall = now;
func.apply(this, args);
}
};
}
Throttle vs Debounce
Understanding when to use each technique is crucial for performance optimization.
When to Use Throttle
Use throttle when you want to limit the rate of function calls but still get regular updates.
// Scroll position updates - need regular updates
const throttledScroll = throttle(() => {
updateScrollIndicator(window.scrollY);
updateLazyImages();
}, 200);
// Mouse move tracking - need regular position updates
const throttledMouseMove = throttle((e) => {
updateCursor(e.clientX, e.clientY);
}, 50);
When to Use Debounce
Use debounce when you want to wait for a pause before executing.
// Search input - wait for user to finish typing
const debouncedSearch = debounce((query) => {
fetchResults(query);
}, 300);
// Window resize - wait for resize to finish
const debouncedResize = debounce(() => {
recalculateLayout();
}, 250);
Side-by-Side Comparison
// Throttle: executes every 200ms during continuous events
const throttled = throttle(log, 200);
// Events: |||||||||||||||||||||||||||||||||
// Output: |---200ms---|---200ms---|---200ms---|
// Debounce: executes once after 200ms of no events
const debounced = debounce(log, 200);
// Events: |||||||||||||||||||||||||||||||||
// Output: |---200ms---| (single call)
Combining Both
// For resize: debounce the final recalculation,
// throttle the intermediate updates
function handleResize() {
// Throttle visual updates
throttledUpdate();
// Debounce final calculation
debouncedRecalculate();
}
Practice Problems
Create a reusable React component implementing Throttling. Include proper state management and accessibility.
Solution
// Production-ready component with:
// - Proper TypeScript types
// - Accessibility (ARIA)
// - Error boundaries
// - Loading states
// - Memoization where neededWrite unit and integration tests for Throttling using React Testing Library.
Solution
// Test coverage:
// 1. Rendering tests
// 2. Interaction tests
// 3. Edge case tests
// 4. Accessibility testsOptimize Throttling for performance. Consider memoization, code splitting, and bundle size.
Solution
// Optimization techniques:
// 1. React.memo / useMemo / useCallback
// 2. Code splitting with lazy()
// 3. Virtual scrolling for lists
// 4. Image lazy loading
// 5. Bundle analysisQuiz
1. What does throttle do?
2. When should you use throttle instead of debounce?
3. What happens during a throttled interval?
4. What is the difference between throttle and debounce?
Flashcards
Question
What is throttling?
Click to reveal answer
Answer
A technique that limits how often a function executes, ensuring at most one call per specified interval.
Question
When should you use throttle?
Click to reveal answer
Answer
For events that fire continuously and you need regular updates: scroll, mouse move, resize.
Question
Throttle vs Debounce?
Click to reveal answer
Answer
Throttle: limits rate, fires at intervals. Debounce: waits for pause, fires once after delay.
Question
How does throttle work internally?
Click to reveal answer
Answer
Uses a flag (inThrottle) and setTimeout. When called, executes and sets flag. Flag resets after interval.
Question
What is Throttling?
Click to reveal answer
Answer
Throttling is a key concept in frontend development.
Revision Notes
Key Takeaways
- 1.Throttle limits execution to once per interval
- 2.Use throttle for continuous events like scroll
- 3.Debounce waits for pause, throttle limits rate
- 4.Implementation uses a flag and setTimeout
- 5.Choose based on whether you need regular updates or final state
Interview Tips
- •Explain the difference between throttle and debounce clearly
- •Implement throttle from scratch
- •Discuss when to use each technique with examples
- •Explain how to combine both for optimal performance
Cheat Sheet
Throttling Cheat Sheet
What is it?
Limits function calls to at most once per interval.
Basic Implementation
function throttle(func, limit) {
let inThrottle = false;
return function(...args) {
if (!inThrottle) {
func.apply(this, args);
inThrottle = true;
setTimeout(() => inThrottle = false, limit);
}
};
}
Throttle vs Debounce
- Throttle: Rate limiting, fires at intervals
- Debounce: Wait for pause, fires once
Common Use Cases
- Scroll events
- Mouse move tracking
- Button clicks
- Game loops