Debounce in JavaScript: Enhance Frontend Performance

In today’s world, optimizing Frontend performance is crucial for delivering fast and responsive user experiences. One common technique used to achieve this is Debounce, a method that helps control the frequency of function calls, particularly useful for handling events like scroll, resize, or input changes. In this article, we’ll delve into the concept of Debounce in JavaScript, explore its benefits, and learn how to implement it effectively in our projects.

Understanding Debounce:

Debounce is a technique used to limit the rate at which a function is called, especially in scenarios where the function is invoked frequently, such as user input events. By delaying the execution of the function until after a certain period of inactivity, debounce helps improve performance by reducing unnecessary function calls and avoiding excessive processing.

Key Benefits of Debounce:

  • Prevents excessive function calls: Debounce ensures that a function is only called once after a specified delay, even if it is triggered multiple times within that period.
  • Improves UI responsiveness: By delaying the execution of expensive operations, debounce helps maintain a smooth and responsive user interface, especially in scenarios with rapid user interactions.
  • Reduces unnecessary processing: Debounce minimizes unnecessary processing by ignoring intermediate function calls, focusing only on the final invocation after the delay period.

Implementing Debounce:

There are various ways to implement debounce in JavaScript, but one common approach involves using a timer to delay the function execution. Here’s a basic debounce function, the callback function will be called after the delay time period.

function debounce(func, delay) {
  let timer; 
  return function(...args) {
    clearTimeout(timer); 
    timer = setTimeout(() => {
      func.apply(this, args);
    }, delay); 
  }; 
}

Debounce code in an understandable way.

const debounce = (callback, delay) => {
  let timer;
  return (...args) => {
    clearTimeout(timer);
    timer = setTimeout(() => {
      callback(...args);
    }, delay);
  };
};

Let’s say, there is an input(username), when the user types something in the username field, then we need to call an API containing all the usernames, based on what the user typed we need to show different users who match the typed input.

<div className="App">
      <input placeholder="username" onChange={(e) => handleChange(e)} />
</div>

Here is the handleChange, We should not call the API for every character that we type in input, in that case, we use Debounce saying at which interval we will be calling the API. In the below example, after 200ms when the user stops inputting in the username field, then we will call the API. getData() is the method to fetch the data from API.

const handleChange = (e) => {
    setSearch(e.target.value);
    const debounceFun = debounce(200, getData);
    debounceFun();
};

Practical Applications:

Debounce is commonly used in various frontend development scenarios, including:

  • Handling user input events like keystrokes or form submissions
  • Implementing auto-complete or search functionality with real-time filtering
  • Optimizing performance in scrolling or resizing event listeners

Many interviewers asked me about this Debounce concept and asked me to solve a practical question based on the Debounce concept. Below is one of the questions related to Debounce that was asked in the Rizzle interview.

Interviewer asked to create an input with typehead functionality, when user types something then respective search results should be visible, When user presses then we should do an API call, This type input should have a debounce functionality and abort controller functionality.