DEV Community

loading...
Cover image for Ever heard of debouncing in   in javascript , What is it ?

Ever heard of debouncing in in javascript , What is it ?

ashishjshetty profile image Ashish J shetty ・3 min read

If you are here you probably might know or want to learn the debouncing practice used to improve the web app performance.

Purpose of Debounce

Debouncing is the technique used to limit the number of times a function can be executed.

How it works?.

A debounce function will wait until the last time the function is called and fire after a predefined amount of time or once the event firing becomes inactive .

Din't get it ? sit tight let's see what exactly the above statement means .

Debrief

Lets take an example of search bar in a e-commerce app.
For suppose user wants to search for "school bag" , the user starts typing in letter by letter in the search bar . After typing each letter there will be an Api call happening to fetch the product for the user search text , In this example 10 calls will be done from browser to server. Think of the scenario that when millions of users making the same search there by making billions of Api calls . Making huge number of Api's at a time will definitely leads to slower performance .

Debouncing to the rescue.

lets mock this scenario , Lets create a search box on each key stroke it will call a getData Api , here we will not call an actual Api but lets console log a text.
Our HTML file

<!DOCTYPE html>
<html>
  <head>
    <title>Parcel Sandbox</title>
    <meta charset="UTF-8" />
    <script src="./src/index.js"></script>
  </head>

  <body>
    <div id="app">
      <input type="text" id="userInput" />
    </div>
  </body>
</html>

Enter fullscreen mode Exit fullscreen mode

our javascript file.

const inputBox = document.querySelector("#userInput");

function getData() {
  console.log("get Data api called ");
}

inputBox.onkeyup = getData;

Enter fullscreen mode Exit fullscreen mode

the result:
Debouncing
Here you can see that normal execution will make function call for each key up event, if the function is performing the heavy task like making an Api call then this could become a costly operation with respect to load on the server and web app performance. let's find a way to improve this using debouncing.

updated javascript code

const inputBox = document.querySelector("#userInput");

function getData() {
  console.log("get Data api called ");
}

const debounce = (fn, delay) => {
  let timer
  return (...args) => {
    clearTimeout(timer)
    timer = setTimeout(() => fn(...args), delay)
  }
}
const debouncedFunction = debounce(getData, 300);

inputBox.addEventListener("keyup", () => {
  debouncedFunction();
});

Enter fullscreen mode Exit fullscreen mode

(thanks to @lexlohr for suggesting a straightforward implementation using modern javascript in the comment section).
The Result
debounced function

The result is just wow!! we could reduce so much of load from the server and the better performing webapp.

let's go through the code, a debounced function will typically return you a another function with the setTimeout() , In the above code you might wondering why we have cleared the timer with clearTimeout() first and then set the timer again with setTimeOut() this is to get the delay i.e the repeated call will eventually clear the timer so api call will never happen until the difference between two function call is more than that of delay which is in this case 300 milliseconds so when a user starts typing if the difference between the last letter typed and next letter to be typed is more than the delay provided the function will be called.

You might argue what we achieved with debouncing can also be achieved with Throttling it wouldn't be wrong but these two have some subtle differences and different use cases .

If you are wondering what Throttling is, it is also a technique to reduced the number of times a function is called but let's keep the differences and use cases for a different blog post .

Hope I made debouncing clear to you guys!! , for any correction or suggestions please comment down .

Till then Happy Javascripting ❤
Peace out ✌️

Discussion (7)

Collapse
lexlohr profile image
Alex Lohr

It's a bit more straight forward in modern JavaScript:

const debounce = (fn, delay) => {
  let timer
  return (...args) => {
    clearTimeout(timer)
    timer = setTimeout(() => fn(...args), delay)
  }
}
Enter fullscreen mode Exit fullscreen mode
Collapse
lukeshiru profile image
LUKE知る

Indeed, and you can also make it a curried function, and even add types with JSDocs!

/** @param {number} delay */
const debounce = delay => {
    /** @type {number} */
    let timer;

    /**
     * @template {Function} Callback
     * @param {Callback} callback
     * @returns {(...parameters: Parameters<Callback>) => void}
     */
    const debounced =
        callback =>
        (...parameters) => {
            clearTimeout(timer);
            timer = setTimeout(() => callback(...parameters), delay);
        };

    return debounced;
};

const debounce100 = debounce(100);
const debounce100Log = debounce100(console.log);

debounce100Log("hello");
debounce100Log("world");
Enter fullscreen mode Exit fullscreen mode
Collapse
ashishjshetty profile image
Ashish J shetty Author

Thank you !!
, this is also a great suggestion.

Collapse
ashishjshetty profile image
Ashish J shetty Author

thank you , this looks simpler.

Collapse
jwhenry3 profile image
Justin Henry

The title is a perfect explanation of what debounce is. "Debouncing in in javascript", you probably read that as "Debouncing in javascript" because your brain debounced the repeated "in". That is the gist of it, plain and simple. See repeating events that shouldn't be handled, wait until the last execution within a set timeframe and then act on it.

Collapse
aarone4 profile image
Aaron Reese

I had to read the post twice to understand what you were saying. For clarity for other readers, the debouncedFunction fires on every keyup however the first thing that happens is to clear and reset the timer so the inner get data function does not get called until the outer function HAS NOT fired for 300ms.
I know you have said you will keep throttling for another post but the key difference is that throttling would fire the inner function immediately and then ignore any other calls during the timeout period.

Collapse
ashishjshetty profile image
Ashish J shetty Author

Thanks for the feedback !. will definitely update the content to make it more understandable .

Forem Open with the Forem app