What it is: Debouncing ensures a function runs only after a certain amount of time has passed without it being called again. If the event is triggered again before the delay is over, the timer resets.
When to use it:
- Search inputs (wait until the user stops typing before making an API call)
- Resizing the window (run expensive layout calculations after the user finishes resizing)
- Auto-saving forms (save only when the user pauses)
Example in React (Search Input):
import { useState, useEffect } from 'react';
function SearchBox() {
const [query, setQuery] = useState('');
const [debouncedValue, setDebouncedValue] = useState(query);
useEffect(() => {
const handler = setTimeout(() => {
setDebouncedValue(query);
}, 500); // 500ms delay
return () => clearTimeout(handler);
}, [query]);
useEffect(() => {
if (debouncedValue) {
console.log('Fetching data for:', debouncedValue);
}
}, [debouncedValue]);
return <input value={query} onChange={(e) => setQuery(e.target.value)} />;
}How it works: User types "react" quickly → API request is made only after the user stops typing for 500ms.
What it is: Throttling ensures a function runs at most once in a specified interval, no matter how many times it’s triggered.
When to use it:
- Scroll events (e.g., infinite scroll checks)
- Mouse movement tracking (e.g., for a game or UI element)
- Button spam prevention (only allow clicks every X ms)
Example in React (Scroll Event):
import { useEffect } from 'react';
function ThrottledScroll() {
useEffect(() => {
let lastCall = 0;
function handleScroll() {
const now = Date.now();
if (now - lastCall >= 200) {
// 200ms throttle
console.log('Scroll position:', window.scrollY);
lastCall = now;
}
}
window.addEventListener('scroll', handleScroll);
return () => window.removeEventListener('scroll', handleScroll);
}, []);
return <div style={{ height: '200vh' }}>Scroll me</div>;
}How it works: Even if the user scrolls rapidly, the event runs once every 200ms max.
| Feature | Debounce | Throttle |
|---|---|---|
| Purpose | Waits until no more calls happen | Limits calls to once per time period |
| Best for | Search boxes, input events | Scroll, resize, mousemove |
| Executes | After user stops triggering | At regular intervals while triggering |
Instead of manually coding, you can use lodash or underscore:
import { debounce, throttle } from 'lodash';
// Debounce example
const handleInput = debounce((val) => {
console.log('Searching for', val);
}, 500);
// Throttle example
const handleScroll = throttle(() => {
console.log('Scroll position:', window.scrollY);
}, 200);