In JavaScript, whenever we’re attaching a performant-heavy function to an event listener, it's considered best practice to control how often the function is called. Here we’ll take a look at how to implement debounce and throttle functions for regulating events.
First, lets try to understand the power of event listeners with this example. The code is written in such a way that whenever there is a cursor movement, it gets registered as a event.
As we can see on a 5 sec cursor, event has been triggered almost 190 times!! This can be great at times, but also cause performance issues.
Whenever we’re attaching a performant-heavy function to an event listener, it’s considered best practice to control how often the function is called.
Debounce and Throttle are two methods for optimising performance of scripts by controlling how often an event is called.
Imagine building a shopping cart where user has picked lots of items and finally clicking to the Pay the Price options. But what if the user accidently clicks on the same button twice in a row. So does that mean the order will go twice? Well that depends entirely on how the app is created and functionality is provided , but in a normal situation we don't want that thing to happen
So here comes debounce function to rescue!!
Debounce
When we are working with event listeners, debounce is of greater use!
const btn = document.querySelector("#btn");
const msg = document.querySelector("#msg");
btn.addEventListener("click",debounce((e) =>
{
msg.innerHTML = `I got clicked`;
}, 2000)
);
If we try to run it as it is , we will get a error because we havent defined the debounce function yet, so lets write our debounce function and logic to our code
const debounce = (fn, delay) => {
let timeoutId;
return function (...args) {
if (timeoutId) {
clearTimeout(timeoutId);
}
timeoutId = setTimeout(() => {
fn(...args);
}, delay);
};
};
The debounce function takes in two params, one is a callback function and other is the time delay. The function could have a bunch of arguments. The main logic here is the setTimeout function in which we will call our function with the given delay. Now lets execute the code
As we can see, even if the button is clicked several times, code will get executed only after the last click with the delay of 2 secs.
Throttle
Throttle calls a function at intervals of a specified amount of time while the user is carrying out an event.
The code is similar to that of debounce, but the functionality is a bit different
const btn = document.querySelector("#btn");
const msg = document.querySelector("#msg");
let time = 0;
const throttle = (fn, delay) => {
let last = 0;
return (...args) => {
const now = new Date().getTime();
if (now - last < delay) {
return;
} else {
last = now;
return fn(...args);
}
};
};
btn.addEventListener(
"click",
throttle((e) => {
time++;
msg.innerHTML = `I got clicked ${time} times`;
}, 5000)
);
Output:
As seen in the output, the click made in between the delay time doesnt get counted.
Difference with help of diagram: