Skip to content
exercises
JavaScript

Debounce & throttle, by hand

Two utilities I now reach for monthly.

IntermediateCourse

Implement debounce and throttle from first principles. These two utilities are the foundation of performant event handling.

The Problem

Certain events fire a lot — mousemove, scroll, resize, typing in a search box. If you run expensive logic on every single event, you’ll lock up the UI or hammer the server.

debounce and throttle are two strategies to reduce how often a function actually runs.

Debounce

Debounce says: “I’ll wait until the user stops doing something, then run the function once.”

Perfect for: search-as-you-type, form validation, resize handlers.

function debounce(fn, delay) {
let timeoutId;
return function (...args) {
clearTimeout(timeoutId);
timeoutId = setTimeout(() => fn(...args), delay);
};
}

Every time the function is called, we clear the previous timer and set a new one. The function only actually runs after delay milliseconds of silence.

Throttle

Throttle says: “Run this function at most once every N milliseconds.”

Perfect for: scroll event handlers, mouse tracking, game loops.

function throttle(fn, interval) {
let lastRun = 0;
return function (...args) {
const now = Date.now();
if (now - lastRun >= interval) {
fn(...args);
lastRun = now;
}
};
}

We track the last time the function ran and refuse to run it again until interval milliseconds have passed.

Real Example

// Debounce: search fires once when typing stops
const handleSearch = debounce((query) => {
fetch(`/api/search?q=${query}`);
}, 500);
input.addEventListener("input", (e) => handleSearch(e.target.value));
// Throttle: scroll handler runs at most every 100ms
const handleScroll = throttle(() => {
console.log("Scroll position:", window.scrollY);
}, 100);
window.addEventListener("scroll", handleScroll);

Why It Matters

Once you understand these patterns, you can apply them anywhere. API calls, UI updates, animations — they all benefit from smart event handling.

I reach for these utilities multiple times a month. Knowing how to implement them from scratch means I understand what they’re actually doing, not just using them as black boxes.