April 16, 2025

Debounce và Throttle trong JavaScript: Khi nào dùng và vì sao?
Hiểu sự khác nhau giữa debounce và throttle trong JavaScript và cách áp dụng chúng hiệu quả
Debounce và Throttle là gì?
Khi người dùng tương tác với trang web – như gõ tìm kiếm, cuộn chuột, thay đổi kích thước trình duyệt – những hành động này có thể xảy ra liên tục và với tần suất rất cao. Nếu mỗi lần tương tác đó đều khiến JavaScript xử lý ngay lập tức, ứng dụng sẽ bị chậm, giật lag, thậm chí treo trình duyệt.
Đó là lý do tại sao chúng ta cần đến debounce và throttle – hai kỹ thuật đơn giản nhưng cực kỳ hữu ích để kiểm soát tần suất gọi hàm, giúp nâng cao hiệu suất và trải nghiệm người dùng.
1. Debounce là gì?
Debounce là một cơ chế giúp trì hoãn việc thực thi một hàm cho đến khi người dùng dừng tương tác trong một khoảng thời gian nhất định.
Nói cách khác, nếu người dùng cứ tiếp tục tương tác (ví dụ: tiếp tục gõ ký tự vào ô tìm kiếm), hàm sẽ không được gọi. Chỉ khi họ dừng lại (ví dụ: dừng gõ trong 300ms), hàm mới được thực thi.
🎯 Ví dụ thực tế:
Bạn đang làm tính năng tìm kiếm realtime. Mỗi khi người dùng gõ, bạn gọi API để lấy kết quả. Nếu họ gõ liên tục 10 ký tự, bạn không muốn gọi API 10 lần – mà chỉ gọi khi họ gõ xong. Debounce giúp bạn làm điều đó.
function debounce(fn, delay) {
let timeout;
return (...args) => {
clearTimeout(timeout);
timeout = setTimeout(() => fn(...args), delay);
};
}
const handleSearch = debounce((query) => {
console.log("Gọi API với:", query);
}, 300);
input.addEventListener("input", (e) => {
handleSearch(e.target.value);
});
2. Throttle là gì?
Throttle hoạt động ngược lại một chút. Thay vì chờ người dùng dừng lại, throttle giới hạn tần suất thực thi: cứ mỗi khoảng thời gian cố định, hàm chỉ được gọi một lần, bất kể người dùng tương tác bao nhiêu.
🎯 Ví dụ thực tế:
Bạn muốn cập nhật vị trí cuộn trang khi người dùng scroll. Scroll có thể xảy ra hàng chục lần mỗi giây. Nếu mỗi lần đều xử lý logic nặng, trình duyệt sẽ chậm thấy rõ. Throttle giúp bạn chỉ gọi hàm xử lý scroll mỗi 200ms chẳng hạn.
function throttle(fn, interval) {
let lastTime = 0;
return (...args) => {
const now = Date.now();
if (now - lastTime >= interval) {
lastTime = now;
fn(...args);
}
};
}
const handleScroll = throttle(() => {
console.log("Scroll vị trí:", window.scrollY);
}, 200);
window.addEventListener("scroll", handleScroll);
3. Khi nào dùng Debounce và Throttle?
Tình huống sử dụng | Nên dùng | Giải thích |
---|---|---|
Người dùng gõ ô tìm kiếm | debounce | Chờ người dùng gõ xong mới gọi API |
Resize cửa sổ trình duyệt | debounce | Tránh gọi lại logic resize liên tục |
Theo dõi cuộn trang | throttle | Cập nhật thông tin cuộn mỗi khoảng thời gian |
Kéo thả hoặc di chuyển chuột | throttle | Giới hạn số lần xử lý vị trí chuột |
Validate form khi nhập | debounce | Chờ người dùng nhập xong trước khi kiểm tra |
4. So sánh nhanh giữa Debounce và Throttle
Debounce | Throttle | |
---|---|---|
Cách hoạt động | Chờ đến khi không còn tương tác thì mới gọi hàm | Gọi hàm đều đặn sau mỗi khoảng thời gian cố định |
Tần suất thực thi | Một lần sau cùng | Nhiều lần nhưng giới hạn tần suất |
Dễ hiểu như | “Chờ yên mới làm” | “Làm đều đặn, không quá thường xuyên” |
Trường hợp sử dụng | Input, search, resize | Scroll, mouse move, resize |
Dưới đây là phần bổ sung về cách sử dụng Lodash với debounce và throttle:
5. Dùng Lodash để Cải Thiện Debounce và Throttle
Lodash cung cấp sẵn các hàm debounce
và throttle
, giúp bạn dễ dàng sử dụng mà không cần phải tự cài đặt lại các giải thuật.
🎯 Cách sử dụng Lodash với Debounce
Lodash cung cấp một hàm debounce
rất dễ sử dụng, cho phép bạn chỉ cần truyền vào hàm cần gọi và thời gian trì hoãn. Ví dụ:
import { debounce } from "lodash"; const handleSearch = debounce((query) => { console.log("Calling API with:", query); }, 300); input.addEventListener("input", (e) => { handleSearch(e.target.value); });
🎯 Cách sử dụng Lodash với Throttle
Tương tự như debounce
, Lodash cũng cung cấp một hàm throttle
để giới hạn tần suất thực thi hàm:
import { throttle } from "lodash";
const handleScroll = throttle(() => {
console.log("Scroll position:", window.scrollY);
}, 200);
window.addEventListener("scroll", handleScroll);
Sử dụng Lodash giúp bạn tiết kiệm thời gian và tránh lỗi trong quá trình cài đặt lại các hàm debounce và throttle. Hơn nữa, Lodash còn hỗ trợ thêm nhiều tính năng tiện ích như kiểm tra kiểu dữ liệu, làm việc với mảng và đối tượng, giúp mã nguồn của bạn gọn gàng và dễ duy trì hơn.
6. Kết luận
Cả debounce và throttle đều là những kỹ thuật cực kỳ hữu ích để tối ưu hiệu suất trong các ứng dụng web hiện đại. Biết cách sử dụng đúng lúc, đúng chỗ không chỉ giúp code của bạn chạy mượt hơn mà còn nâng cao trải nghiệm người dùng một cách rõ rệt.
Hãy xem lại các tính năng của bạn – có thể đang có những đoạn code đang “chạy quá sức” mà chỉ cần một dòng debounce hoặc throttle là đủ để “giải cứu” chúng rồi đấy!
Debounce vs Throttle in JavaScript: When and Why to Use Them?
Understand the difference between debounce and throttle in JavaScript and how to apply them effectively
What are Debounce and Throttle?
When users interact with your website – like typing into a search bar, scrolling the page, or resizing the window – those actions can happen frequently and rapidly. If your JavaScript code responds to every single event immediately, performance can degrade quickly.
That’s why debounce and throttle are essential techniques to control how often a function is executed, helping your application remain smooth and responsive.
1. What is Debounce?
Debounce ensures that a function is only executed after a specific amount of time has passed without any further interaction.
In other words, if the user keeps triggering the event (e.g., typing), the function will be delayed until they stop for a set time (e.g., 300ms).
🎯 Real-world example:
In a live search feature, you don’t want to call the API every time the user types a letter. Debounce waits until the user finishes typing and then makes a single call.
function debounce(fn, delay) {
let timeout;
return (...args) => {
clearTimeout(timeout);
timeout = setTimeout(() => fn(...args), delay);
};
}
const handleSearch = debounce((query) => {
console.log("Calling API with:", query);
}, 300);
input.addEventListener("input", (e) => {
handleSearch(e.target.value);
});
2. What is Throttle?
Throttle limits how often a function can be called by only allowing one call per specified time interval.
🎯 Real-world example:
When tracking scroll events, you don’t want to run your logic dozens of times per second. Throttle ensures your function runs at regular intervals – say every 200ms – no matter how often the user scrolls.
function throttle(fn, interval) {
let lastTime = 0;
return (...args) => {
const now = Date.now();
if (now - lastTime >= interval) {
lastTime = now;
fn(...args);
}
};
}
const handleScroll = throttle(() => {
console.log("Scroll position:", window.scrollY);
}, 200);
window.addEventListener("scroll", handleScroll);
3. When to Use Debounce vs Throttle?
Use Case | Choose | Reason |
---|---|---|
Typing in search input | debounce | Wait until the user stops typing |
Window resize | debounce | Avoid frequent layout recalculations |
Scroll tracking | throttle | Limit how often logic runs |
Mouse move tracking | throttle | Prevent performance issues |
Input validation | debounce | Reduce unnecessary validations |
4. Quick Comparison
Debounce | Throttle | |
---|---|---|
How it works | Waits for inactivity before running function | Runs function at regular intervals |
Execution rate | Once, after delay | Many times, but limited |
Think of it like | “Wait until user stops” | “Run every X ms” |
Best for | Search, resize | Scroll, drag, mouse movement |
Dưới đây là phần dịch sang tiếng Anh:
5. Using Lodash to Improve Debounce and Throttle
Lodash provides ready-made debounce
and throttle
functions, making it easier to use without needing to implement the algorithms from scratch.
🎯 How to Use Lodash with Debounce
Lodash provides a debounce
function that is simple to use, allowing you to just pass in the function you want to call and the delay time. For example:
import { debounce } from "lodash"; const handleSearch = debounce((query) => { console.log("Calling API with:", query); }, 300); input.addEventListener("input", (e) => { handleSearch(e.target.value); });
🎯 How to Use Lodash with Throttle
Similar to debounce
, Lodash also provides a throttle
function to limit the frequency of function execution:
import { throttle } from "lodash";
const handleScroll = throttle(() => {
console.log("Scroll position:", window.scrollY);
}, 200);
window.addEventListener("scroll", handleScroll);
Using Lodash helps you save time and avoid errors when re-implementing debounce and throttle functions. Moreover, Lodash also supports many other useful utilities like type checking, array and object manipulation, making your code more concise and easier to maintain.
6. Conclusion
Debounce and throttle are powerful techniques that help you control how often your functions execute, making your web apps more efficient and user-friendly.
Next time you're working with real-time inputs or high-frequency events, consider whether your code needs a bit of “restraint” — and let debounce or throttle handle it for you!