November 12, 2024
Avoid Excessive Requests with Debounce
-
Blas Fernández
When developing web applications, it's common to need to make backend requests while users enter data in text fields, such as in a search box. While this isn't a problem in applications with low traffic, the situation changes dramatically in systems handling thousands of simultaneous users. In these cases, each keystroke could generate a request that interacts with the database, which can cause serious performance issues.
To solve this, we need to implement a mechanism that controls the frequency of requests. Instead of creating an algorithm from scratch, we can use a proven and efficient technique known as debounce, which allows us to manage these requests optimally.
Debounce works like a smart timer that waits for the user to finish typing before executing the action. For example, if we set a wait time of 500 milliseconds, the debounce function:
- Detects the first keystroke but doesn't execute the request immediately
- Starts a 500ms timer
- If the user presses another key before the time expires, it resets the timer
- Only when the user stops typing and 500ms have passed, the request is finally executed
This means that if a user quickly types "programming", instead of making 12 requests (one for each letter), only one request will be executed with the complete word.
Let's look at a practical implementation example:
function debounce(func, wait) {
let timeout;
return function executedFunction(...args) {
const later = () => {
clearTimeout(timeout);
func(...args);
};
clearTimeout(timeout);
timeout = setTimeout(later, wait);
};
}
// Usage example
const searchProducts = debounce((text) => {
// Make backend request
console.log('Searching:', text);
}, 500);
// In the search field
searchInput.addEventListener('input', (e) => {
searchProducts(e.target.value);
});
With this technique, we achieve a better user experience and reduce the load on our servers by minimizing unnecessary requests.