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>
our javascript file.
const inputBox = document.querySelector("#userInput");
function getData() {
console.log("get Data api called ");
}
inputBox.onkeyup = getData;
the result:
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();
});
(thanks to @lexlohr for suggesting a straightforward implementation using modern javascript in the comment section).
The Result
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 ✌️
Top comments (6)
It's a bit more straight forward in modern JavaScript:
thank you , this looks simpler.
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.
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.
Thanks for the feedback !. will definitely update the content to make it more understandable .
Thank you !!
, this is also a great suggestion.