Sajiron
In modern web applications, user interactions like typing, scrolling, and resizing can fire events dozens of times per second. If we handle every single event as it comes, we can easily end up with performance issues.
That’s where debouncing and throttling come in — two powerful techniques to control the rate of execution of functions triggered by frequent events.
In this post, we’ll break down:
What debouncing and throttling mean
How they work with simple code examples
When to use each
Performance implications
Imagine you have this:
window.addEventListener("resize", () => {
console.log("Resized!");
});
Every pixel change fires the resize
event — this could be hundreds of times per second, completely flooding your console or overloading logic like layout reflows or API calls.
We need to control how often the function runs. Let’s explore how:
Debouncing waits until a function hasn’t been called for a while, then executes it.
Think of it like: "Wait until the user has stopped typing for 300ms, then send the API request."
function debounce(func, delay) {
let timeoutId;
return function (...args) {
clearTimeout(timeoutId);
timeoutId = setTimeout(() => func.apply(this, args), delay);
};
}
const handleInput = debounce((e) => {
console.log("API called with:", e.target.value);
}, 300);
document.querySelector("input").addEventListener("input", handleInput);
Here, the function only runs 300ms after the user stops typing.
Throttling makes sure a function runs at most once in a specified time interval, even if it's triggered repeatedly.
Think of it like: "Run this scroll handler at most once every 500ms, no matter how often the user scrolls."
function throttle(func, interval) {
let lastTime = 0;
return function (...args) {
const now = Date.now();
if (now - lastTime >= interval) {
lastTime = now;
func.apply(this, args);
}
};
}
const handleScroll = throttle(() => {
console.log("Scroll event processed!");
}, 500);
window.addEventListener("scroll", handleScroll);
Use Case | Technique | Why? |
Search-as-you-type | Debounce | Avoid unnecessary API calls while typing |
Resizing window (re-layouting) | Debounce | Only react after resizing is complete |
Button click spam prevention | Throttle | Limit action firing frequency |
Scroll tracking (e.g., lazy load) | Throttle | Regular, limited updates during scroll |
Feature | Debounce | Throttle |
Reacts after delay? | ✅ Yes | ❌ No (reacts immediately, then skips) |
Best for… | Delaying until idle | Regulating rate |
Frequency | Only once after last call | At most every |
If you don’t want to reinvent the wheel:
lodash.debounce
lodash.throttle
Usage:
import debounce from "lodash.debounce";
import throttle from "lodash.throttle";
Both debouncing and throttling are essential tools in any JavaScript developer’s performance toolkit.
Use debounce when you want to wait for an action to "settle"
Use throttle when you want to limit how often an action occurs
Pick the right one based on the interaction pattern you’re optimizing for.
Build fast and safe frontend apps using Rust and Yew. Learn setup, components, hooks, and WebAssembly—all in a React-like Rust framework.
Explore essential math for machine learning—vectors, matrices, calculus, and probability—explained with beginner-friendly JavaScript code.
Learn data preprocessing in JavaScript for Machine Learning. Clean, transform, and structure data with practical examples to boost ML model accuracy!
Learn the basics of Machine Learning in JavaScript! Explore ML concepts, types, and how JS can power AI in the browser. Start your ML journey today!