β‘ Key Takeaways: Debounce delays function execution. Throttle limits execution frequency. Essential for performance optimization.
Events fire too often. Debounce and throttle control them.
π Debounce – Wait and Execute
// β
Debounce implementation
function debounce(func, delay = 300) {
let timeoutId;
return function (...args) {
clearTimeout(timeoutId);
timeoutId = setTimeout(() => {
func.apply(this, args);
}, delay);
};
}
// β
Use case: Search input
const searchInput = document.getElementById('search');
const searchResults = document.getElementById('results');
const handleSearch = debounce((event) => {
const query = event.target.value;
console.log('Searching for:', query);
// β
API call only after user stops typing
fetch(`/api/search?q=${query}`)
.then(res => res.json())
.then(data => {
searchResults.innerHTML = data.map(item =>
`${item.name}`
).join('');
});
}, 500);
searchInput.addEventListener('input', handleSearch);
// β
Use case: Save on form
const saveForm = debounce(() => {
console.log('Saving form...');
// β
Only saves when user stops editing
saveToDatabase();
}, 1000);
document.getElementById('form').addEventListener('change', saveForm);
β±οΈ Throttle – Execute at Intervals
// β
Throttle implementation
function throttle(func, limit = 300) {
let inThrottle = false;
return function (...args) {
if (!inThrottle) {
func.apply(this, args);
inThrottle = true;
setTimeout(() => {
inThrottle = false;
}, limit);
}
};
}
// β
Use case: Scroll events
const handleScroll = throttle(() => {
const scrollY = window.scrollY;
console.log('Scrolled to:', scrollY);
// β
Update progress bar
const progress = (scrollY / (document.body.scrollHeight - window.innerHeight)) * 100;
document.getElementById('progress-bar').style.width = `${progress}%`;
}, 200);
window.addEventListener('scroll', handleScroll);
// β
Use case: Resize events
const handleResize = throttle(() => {
console.log('Window resized:', window.innerWidth, window.innerHeight);
// β
Update layout (limited frequency)
updateLayout();
}, 500);
window.addEventListener('resize', handleResize);
π‘ Advanced: Immediate Execution
// β
Debounce with immediate execution
function debounceImmediate(func, delay = 300) {
let timeoutId;
let called = false;
return function (...args) {
if (!called) {
func.apply(this, args);
called = true;
}
clearTimeout(timeoutId);
timeoutId = setTimeout(() => {
called = false;
}, delay);
};
}
// β
Use case: First call immediately
const handleClick = debounceImmediate(() => {
console.log('Button clicked');
// β
Immediate feedback
showFeedback();
}, 300);
button.addEventListener('click', handleClick);
π When to Use What
| Scenario | Solution | Example |
|---|---|---|
| Search input | Debounce | Search after typing stops |
| Scroll events | Throttle | Progress bar updates |
| Form save | Debounce | Auto-save after editing |
| Resize events | Throttle | Layout updates |
| Button clicks | Debounce (immediate) | Prevent double clicks |
| API calls | Debounce | Rate limit requests |
