Debouncethrottle in Javascript
Learn about debouncethrottle in javascript with practical examples and code snippets.
Example 1
DEBOUNCE AND THROTTLE IN JAVASCRIPT Techniques to limit the rate of function execution Debounce: Execute function after a delay when user stops triggering event Throttle: Execute function at most once per time period Common Use Cases: - Search input (debounce) - Scroll/resize events (throttle) - Button clicks (debounce) - API calls (both) DEBOUNCE - Execute after delay when events stop Clear previous timeout Set new timeout Example: Search input API call here searchInput.
addEventListener('input', (e) => { debouncedSearch(e.
value); THROTTLE - Execute at most once per time period Example: Scroll event Handle scroll window.
addEventListener('scroll', throttledScroll); Advanced Debounce with Immediate Option Advanced Throttle with Leading/Trailing Practical Examples 1.
Search with Debounce Simulate user typing Only one API call after 500ms of last input 2.
Resize with Throttle Update layout window.
addEventListener('resize', throttledResize); 3.
Button Click Debounce (Prevent Double Submit) button.
addEventListener('click', debouncedSubmit); Custom Implementation with Cancel debouncedFn(); debouncedFn.
cancel(); // Cancel execution Request Animation Frame Throttle Smooth scroll handling Update scroll position Comparison: Debounce vs Throttle Debounce: Wait for pause in events - Good for: Search, form validation, button clicks - Executes: After user stops triggering Throttle: Limit execution frequency - Good for: Scroll, resize, mousemove - Executes: At regular intervals Example timeline: Events: |--|--|--|--|--|--|--|--|--| Debounce: [execute] Throttle: [e][e][e][e][e][e][e][e][e] Real-World Example: Search Component fetch(`/api/search.
q=${query}`).
then(res => res.
then(data => this.
displayResults(data)); this.
searchInput.
addEventListener('input', (e) => { this.
debouncedSearch(e.
value); Performance Considerations 1.
Use debounce for expensive operations (API calls) 2.
Use throttle for frequent UI updates (scroll) 3.
Consider requestAnimationFrame for animations 4.
Clear timeouts when component unmounts 5.
Use appropriate delay values (300ms for search, 16ms for animations).
Code
function debounce(func, delay) { let timeoutId; return function(...args) { clearTimeout(timeoutId); timeoutId = setTimeout(() => { func.apply(this, args); }, delay); }; } const searchInput = document.createElement('input'); const debouncedSearch = debounce((query) => { console.log(`Searching for: ${query}`); }, 300); function throttle(func, delay) { let lastCall = 0; return function(...args) { const now = Date.now(); if (now - lastCall >= delay) { lastCall = now; func.apply(this, args); } }; } const throttledScroll = throttle(() => { console.log('Scrolling...'); }, 200); function advancedDebounce(func, delay, immediate = false) { let timeoutId; return function(...args) { const callNow = immediate && !timeoutId; clearTimeout(timeoutId); timeoutId = setTimeout(() => { timeoutId = null; if (!immediate) { func.apply(this, args); } }, delay); if (callNow) { func.apply(this, args); } }; } function advancedThrottle(func, delay, options = {}) { let lastCall = 0; let timeoutId; const { leading = true, trailing = true } = options; return function(...args) { const now = Date.now(); if (!lastCall && !leading) { lastCall = now; } const remaining = delay - (now - lastCall); if (remaining <= 0 || remaining > delay) { if (timeoutId) { clearTimeout(timeoutId); timeoutId = null; } lastCall = now; func.apply(this, args); } else if (trailing && !timeoutId) { timeoutId = setTimeout(() => { lastCall = leading ? Date.now() : 0; timeoutId = null; func.apply(this, args); }, remaining); } }; } function searchAPI(query) { console.log(`API call for: ${query}`); } const debouncedSearchAPI = debounce(searchAPI, 500); debouncedSearchAPI("j"); debouncedSearchAPI("ja"); debouncedSearchAPI("jav"); debouncedSearchAPI("java"); function handleResize() { console.log('Window resized'); } const throttledResize = throttle(handleResize, 200); function submitForm() { console.log('Form submitted'); } const debouncedSubmit = debounce(submitForm, 1000); function cancellableDebounce(func, delay) { let timeoutId; const debounced = function(...args) { clearTimeout(timeoutId); timeoutId = setTimeout(() => { func.apply(this, args); }, delay); }; debounced.cancel = function() { clearTimeout(timeoutId); }; return debounced; } const debouncedFn = cancellableDebounce(() => { console.log('Executed'); }, 1000); function rafThrottle(func) { let rafId = null; return function(...args) { if (rafId === null) { rafId = requestAnimationFrame(() => { func.apply(this, args); rafId = null; }); } }; } const smoothScroll = rafThrottle(() => { console.log('Smooth scroll'); }); class SearchComponent { constructor() { this.searchInput = null; this.debouncedSearch = debounce(this.performSearch.bind(this), 300); } performSearch(query) { if (query.length < 3) return; console.log(`Searching: ${query}`); } init() { } }
Summary
Understanding debouncethrottle is essential for mastering javascript. Practice these examples and experiment with variations to deepen your understanding.
Key Takeaways
- debouncethrottle is a fundamental concept in javascript
- Practice with these examples to build confidence
- Experiment with variations to explore edge cases
- Understanding debouncethrottle will help you in technical interviews