Debouncing & Throttling
📖 Concept
Debouncing and Throttling are rate-limiting techniques that control how often a function is called.
Debounce — Waits until the user STOPS triggering for N ms, then calls once. Use for: search input, window resize, form validation.
Throttle — Calls at most once every N ms, no matter how often triggered. Use for: scroll events, mouse move, game loops.
🏠 Real-world analogy: Debounce is like an elevator — it waits until people stop pressing buttons, then moves. Throttle is like a turnstile — it lets one person through every few seconds, no matter how many are waiting.
💻 Code Example
1// Debounce implementation2function debounce(fn, delay, { leading = false } = {}) {3 let timer;4 let isLeading = leading;5 return function(...args) {6 if (isLeading && !timer) {7 fn.apply(this, args);8 isLeading = false;9 }10 clearTimeout(timer);11 timer = setTimeout(() => {12 if (!leading) fn.apply(this, args);13 timer = null;14 isLeading = leading;15 }, delay);16 };17}1819// Throttle implementation20function throttle(fn, limit) {21 let inThrottle = false;22 let lastArgs = null;23 let lastThis = null;24 return function(...args) {25 if (!inThrottle) {26 fn.apply(this, args);27 inThrottle = true;28 setTimeout(() => {29 inThrottle = false;30 if (lastArgs) {31 fn.apply(lastThis, lastArgs);32 lastArgs = null;33 lastThis = null;34 }35 }, limit);36 } else {37 lastArgs = args;38 lastThis = this;39 }40 };41}4243// Usage examples44const searchInput = document.querySelector("#search");45const handleSearch = debounce((query) => {46 console.log("Searching:", query);47 // fetch(`/api/search?q=${query}`)48}, 300);49searchInput.addEventListener("input", (e) => handleSearch(e.target.value));5051const handleScroll = throttle(() => {52 console.log("Scroll position:", window.scrollY);53}, 200);54window.addEventListener("scroll", handleScroll);5556// requestAnimationFrame throttle (60fps)57function rafThrottle(fn) {58 let ticking = false;59 return function(...args) {60 if (!ticking) {61 requestAnimationFrame(() => {62 fn.apply(this, args);63 ticking = false;64 });65 ticking = true;66 }67 };68}
🏋️ Practice Exercise
Mini Exercise:
- Implement a search bar with debounced API calls
- Build a scroll position indicator with throttled updates
- Create a "Save draft" feature that debounces saving to localStorage
- Implement a window resize handler with throttling
⚠️ Common Mistakes
Confusing debounce and throttle — debounce waits for inactivity, throttle limits frequency
Creating new debounced/throttled functions on every render — memoize or define outside the render
Not preserving
thiscontext — use.apply(this, args)inside the wrapperForgetting to cancel debounce/throttle on component unmount — leads to memory leaks or errors
Setting delay too long (missed updates) or too short (not effective) — benchmark for your use case
💼 Interview Questions
🎤 Mock Interview
Mock interview is powered by AI for Debouncing & Throttling. Login to unlock this feature.