Web VitalsIntermediate
What is throttle? How do you implement a throttle function?
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
resizewhen 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
_.throttlebehaviour. - 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
