Debouncing in JavaScript

Debouncing in JavaScript

Why Debouncing?

If you've ever worked with an API and implemented a Search feature, then you must have noticed how the API call is made every single time you add/delete a character in the search bar.

Imagine this happening in a website having a huge codebase, such as Amazon or Flipkart. API calls are expensive, and making an API call on change of every single character will surely affect the performance of your website.

This is where Debouncing comes to your rescue.

Debouncing is a concept that ensures that any particular event happens only after a delay of a specific time

In other words,

Debouncing is a programming paradigm that reduces the number of expensive tasks, which are performed only after a delay of a specific time interval.

What happens without debouncing?

Let's assume we have an input element. Below is the code of the HTML file:

<input
    type="text"
    placeholder="Type something..."
/>

Now, we want to execute search for the input value by making an API call. In the JavaScript file, let's attach an event listener to the input element.

const input = document.querySelector("input");
input.addEventListener("input", executeSearch);

Here, we have an executeSearch() function which is called everytime the value inside the input element changes.

The executeSearch() would be responsible for fetching data by making an API call:

let counter = 1;

const executeSearch = () => {
    // API call goes here...
    console.log(`Called ${counter++} times`);
};

We also have a counter variable to keep a track of the number of times the executeSearch() function was called.

Here is a live demo of the above code. Observe the console to know the actual number of times the request was fired.

without debouncing cropped.gif

As you can see, the executeSearch() function runs every time we type a character in the input.

This is quite expensive, right? What if we had a way to reduce the number of times the API call was made. Well, we do have. That's exactly how debouncing helps us!

How does Debouncing work?

Take the same input element that we saw above. Here, onchange of input value, we will not call the executeSearch() function, but we will call the debounce() function with two parameters, which will inturn call executeSearch() after a certain delay.

The first parameter will be the instance of our executeSearch function, the second being the delay (in ms). Below is our updated code:

input.addEventListener("input", debounce(executeSearch, 500));

Here comes the magic! Let's see what the debounce() function does:

const debounce = (fn, delay) => {
    let timer = 0;

    return () => {
      clearTimeout(timer);
      timer = setTimeout(() => {
        fn();
      }, delay);
    };
  };

Simply put, the debounce() function takes in a function that will be executed after a given delay.

Let's first see the output:

with debouncing cropped.gif

In-depth explanation

When the user types the first character "d", i.e. every time the debounce function is called, the previous timer is cleared (this does not make sense for the first invocation, as there was no timer set), and then a new timer is set.

This timer will expire after a delay of 500ms, in our case.

As soon as the user types in another character "e", the previous timer of 500ms is canceled and a new timer is set. This continues until the user stops typing, i.e. when a delay of 500ms is encountered.

In this case, the timer won't get canceled (because the debounce function won't fire again). So, our executeSearch function gets triggered.

This means that the executeSearch function will be invoked only if the delay between two consecutive changes of the input is more than 500ms.

So, unlike the previous example, instead of firing the function on every change of input, our debounce function helps reduce this number by calling the executeSearch function only 1 time i.e. after we have stopped typing and the function encounters a delay of 500ms.

Conclusion

  • Debouncing helps us reduce the number of expensive operations, by performing them only after a certain amount of delay.
  • This technique can be used to drastically improve the performance of your web app.

Can you think of any other use case for Debouncing? Let me know in the comments!

Thank you for reading. Hope you learned something new. Happy coding!