Enhance your website performance — JS Debouncing and Throttling!!

this article,we will discuss about that how we can enhance the performance of website using Denounce and throttle.We will learn these things with proper example that will help to understand the topic in much depth and then you can able to implement these by yourself.

We will see that what is debouncing and throttling? Why we need these? What are the problem we will face without these? How these helpful in those case? How to implement and many more!!!

What is Debouncing and Throttling?

Let’s understand the normal meaning of each word.

Debouncing — De + bouncing

Bouncing is refer to the tendency generate multiple signals action as the contacts close or open b/w two metal at an instance.

Debouncing refers to the tendency to restrict the multiple signals generation at a single instance and try to generate single signal when two metal contact close or open.

Throttling refers to the tendency of blocking or stifle.

In Js , Both are working same as the normal definition describe above .

Debouncing and throttling techniques are used to limit the number of times a function can execute.

In general, How many times a function should be executed that is decided by developer but sometimes developer gives this ability to the user now user can execute that functionality many times at an instance.So here the problems arise.

Without debouncing and throttling!!

For instance ,the function attached to the different types of events like enter input,button click,mouse event ,window resizing and many more.. allow the user to decide when to execute them and how many times to do so.At a time users may perform these actions most frequently than it’s required.

So here the main performance issue comes into the picture.Those unexpected frequent action not good for the performance of website, especially when the function attached to these events performing some heavy computation.

In such case , developer should have to design some techniques to restrict the number of times users can trigger that function.

Let’s take an example to understand the problem in much clear way.

Suppose we have built a website in which a search functionality available.This functionality provides some result when we enter some input. Whenever we types something in the search-bar ,Everytime it makes an API call to fetch the data from the server to get the required result for typed letters in the search-bar.

Let’s have a look at the code. For simplicity, we have not implemented the full -fledged UI and HTTP request logic here because our main focus to Understand the problem we face without debouncing and throttling in easy way without any complexity.

index.html

<html>
<body>
<p>ENTER INPUT TO SEARCH</p>
<input type="text" id="searchBox" />
<p>No of times event fired:<span id='showApiCallcount'></span</p>
</body>
<script src="withoutDebounceThrottle.js"></script>
</html>

withoutDebounceThrottle.js

const  searchBoxDom  =  document.getElementById('showApiCallcount');/* This method represent an API call and  very high logic computing which takes a lot of time to execute */
function makeAPICall() {
...
...
}
/** Added "input" event listener on the text box or search bar**/
searchBoxDom.addEventListener('input', function () {
let apiCountDom = document.getElementById('showCallApicount');
let apiCallCount = apiCountDom.innerHTML || 0;
/**A very heavy method which takes a lot of time to execute**/
makeAPICall();
apiCallCount = parseInt(apiCallCount) + 1;/** Updates the number of times makeAPICall method is called**/
apiCountDom.innerHTML = apiCallCount;
})

In the above,index.html simply defines an input search text box and a p tag which wrapped the text and span tag to display the msg and count of API call.Also we add a script tag to attach a js file named as withoutDebounceAttachment in which write all logic .

In withoutDebounceAttachment.js, we get the DOM access of search box and span count tag. Also binds the oninput event listener of search-box that calls a function whenever we types anything in the search box.

Lets understand the problem now in the above code,suppose makeApiCall function takes 400 ms to fetch the data from an API.Now if the user can types 1 letter per 100 ms,then in this case makeApiCall function called 4 times in 400 ms. So actually, we are making 4 API calls before completed any API task that’s not required ,which will put extra load on the server and performance of the websites will decrease.😮

The right solution in this case is that ,there should be a single API call only after when user has completed typing.But the question is arising that how we will decide that user has stopped typing? In such case we can assumed that if user doesn’t type of 200 ms then he is done with typing.So will invoke the API call only when user doesn’t type for 200 ms.

The techniques of limiting the number of times the user can invoke a function attached to an event listener is debouncing and throttling.

Let’ s understand these two in daily world activity so that you can relate easily!!

Debouncing

Let’s assume you are 8 year old naughty boy and who loves to eat sweets.Today your mom has made few sweets ,but it’s not for you,it’s for the guests! But you wants to eat anyhow so you keeps asking your mom for the sweets.Finally she gives you one.But you are keep asking for more!!After few times later she agree to gives you more but with one condition that if you will remain silent for an hours continuously.This means if you ask in b/w 1 hr then again you have to wait for another 1 hr ,since after last time you ask.

This is what debouncing is!!!!

Debouncing is technique in which ,no matter how times you will fire the event ,the attached function will call only at once for the specified times when user stops the firing last time.

Throttling

Take the same example as above.In this case when you keeps asking for the sweets at first time to your mom. She gives you one.But when you keep asking for another!!! .After few times later she agree to gives you with a condition that you will get after an hour.But still you keep asking but she ignores you totally for an hours.Finally, after an interval of one hour, you get more cake..Same process repeats!!

This is what throttling is!!!!

Throttling is a technique in which, no matter how many times the user fires the event, the attached function will be executed only once in a given time interval.

So whats the difference b/w these two?

Difference b/w Debouncing and Throttling

let’s understand the difference b/w these two using a button click pictorial representation.

We have a button when we click on it what happens in both cases let’s see!!

In the Above picture ,red vertical line(A1…An, & B1..Bn) represents click event and blue line(X1,X2) represent Expected attached function call which is bind with the events and green vertical line(Y1,Y2) represents actual attached function call.And green horizontal line represents interval(We assumed here 2000 ms).

For 1st case ,In General when we continuously click on the button:

Debouncing: Attached function will invoke(Y1) after 200 ms at the end of last continuous click(i.e An)

Throttling: Attached function will invoke(X1) after 200 ms ,after the first continuous click(i.e An)

For 2nd case ,In General when we click again and again but not rapidly on the button within the define delay:

Debouncing: Attached function will invoke (Y2) after 200 ms at the end of last click i.e (Bn )which is just before the define interval.

Throttling: Attached function will invoke(X2) after 200 ms ,after the first first click(i.e Bn)

We required setTimeout function to acheive debouncing and throttling.

setTimeout

setTimeout is a scheduling function in JavaScript that can be used to schedule the execution of any function. It is a web API provided by the browsers and used to execute a function after a specified time. Here’s the basic syntax:

var timerId = setTimeout(callbackFunction, timeToDelay)

JavaScript

The setTimeout function takes input as a callbackFunction that is the function which will be executed after the timer expires, and timeToDelay is the time in milliseconds after which the callbackFunction will be executed.

The setTimeout function returns a timerId, which is a positive integer value to uniquely identify the timer created by the call to setTimeout; this value can be passed to clearTimeout to cancel the timeout.

function delayFuncExec() {
console.log("I will be called after 100 milliseconds");
}
var timerId = setTimeout(delayFuncExec, 100)console.log("Timer Id: " + timerId)

Here, delayFuncExec will be executed after 100 milliseconds. timerId will store the integer returned by the setTimeout function.

clearTimeout

clearTimeout function is used to cancel the timeout previously established by calling the setTimeout function. clearTimeout takes the timerId returned by the setTimeout function as input and cancels its execution. So, if you want to cancel the execution of any setTimeout function, you can use clearTimeout function to cancel it by passing its timerId.

function delayFuncExec() {
/** This statement will not be printed as it will be cancelled by clearTimeout **/
console.log("I will not be executed as I will be cancelled");
}
var timerId = setTimeout(delayFuncExec, 100)
console.log("Timer Id: " + timerId)
clearInterval(timerId)

NOTE: Debouncing and throttling are not something provided by JavaScript itself. They’re just concepts we can implement using the setTimeout web API. Some libraries like loadash provide these methods out of the box.

Implementation of Debouncing in Js

let’s take the above search example with debounce.

You can visualise that,attachFunction has called only once after the 2000 ms when we entered the last digit while events has fired 3 times.let’s see the debounce implementation logic that how we have achieved that.

index.html

<html>
<body>
<p>ENTER INPUT TO SEARCH</p>
<input type="text" id="searchBox" />
<p>No of times event fired:<span id='showEventCallcount'></span</p>
<p>No of times attached function fired:<span id='showAttachFunCallcount'></span</p>
</body>
<script src="withDebounce.js"></script>
</html>

withDebounce.js

const  searchBoxDom  =  document.getElementById('searchBox);
let timeId;
function makeAPICall() {var debounceDom = document.getElementById('showAttachFunCallcount');
var debounceCount = debounceDom.innerHTML || 0;
debounceDom.innerHTML = parseInt(debounceCount) + 1
}//Debouncing logic function
const debounceFun = (fn,delay)=>{
if(timeId){ clearTimeout(timeId);}timeId = setTimeout(()=>{fn();},delay)}// Add "input" event listener on the text box or search barsearchBoxDom.addEventListener('input', function () {var eventCallCountDom = document.getElementById('showEventCallcount');var eventCallCount = eventCallCountDom.innerHTML || 0;eventCallCount = parseInt(eventCallCount) + 1;// Updates the number of times makeAPICall method is called
eventCallCountDom.innerHTML = eventCallCount;
// Debounces makeAPICall method
debounceFun(makeAPICall, 500)
})

All the UI display logic written in index.html to display search-box,count of events fired and counts of attachedFunction triggered which perform heavy computation and api call.

In the withDebounce.js,we have wrapped up the makeAPICall function within debounceFun. We are passing the two param in it i.e makeAPICall and 500.

makeAPICall — The function which perform an api call and conatins heavy Computation logic.

500 — It’s the time delay in milliseconds that we are passing that sets 1000 ms delay after entering the last letter in search-box.

debounFunc() — contains the logic of how and when to triggered attachedFunction i.e(makeAPICall).We have set timeId initially undefined.And triggering the makeAPICall only when timeId is not undefined and the total duration since last letter entered in the search-box is 500 ms. Otherwise don’t trigger the attached Function(i.e makeAPICall).

Implementation of Throttling in Js

let’s take an example.Suppose you want to build a shopping website .In which users have the functionality to select and add the item to the cart.But you want to restrict the problem of continuous click.So you have to implement the logic that allow the user to add the item on first click ,if user click continuously on addItem then only first click will triggered the attached function and rest continuous click will be ignored and after certain delay & the item added successfully in the cart then only next attached function will be triggered.

let’s see how we can acheive this with the help of Throttling!!!!

index.html

<html>
<body>
<button id="addItem">ADD ITEM TO CART</button>
<p>No of times event fired:<span id='showEventCallcount'></span</p>
<p>No of times item added in Cart:
<span id='showAttachFunCallcount'></span</p>
</body>
<script src="withThrottle.js"></script>
</html>

withThrottle.js

let last =0;
let now =0;
addItemToDatabase = ()=>{
var throttleDom = document.getElementById('showAttachFunCallcount');
var throttleCount = throttleDom.innerHTML || 0;
throttleDom.innerHTML = parseInt(throttleCount) + 1
}
const throttleFun = (fn,delay)=>{
now = new Date().getTime();

if(now-last<delay){
return;
}
last = now;
return fn();

}
document.getElementById("addItem").addEventListener("click",()=>{

var eventCallCountDom = document.getElementById('showEventCallcount');
var eventCallCount = eventCallCountDom.innerHTML || 0;
eventCallCount = parseInt(eventCallCount) + 1;
// Updates the number of times addItemToDatabase method is called
eventCallCountDom.innerHTML = eventCallCount;
throttleFun(addItemToDatabase,2000);
})

In the above ,we have written the code in index.html that added button to add items in the cart and <span> and <p> tag to display the count information of event and count of added item in the cart on the UI and bind this to withThrottle.js.

We have bind the click event of addItem button and perform the count info and call the addItemToDatabase function which is attached function wrapped within throttleFun().

We have pass two parameter to throttleFunc same as debounce i.e function and timeDelay. The only difference here is that we have changed the logic of invoking the attached function.

We have take two variable here last and now.last is used to track the time interval 0 when to timeDelay(i.e in this case 2000 ms) when we click the button initially.And now is used to get the current time using Date object.

When the timedelay is greater than (now -last). i.e delay time crossed then only next Attached function (i.e addItemToDatbase) will be triggered otherwise not.

NOTE:- You have noticed that it’s depend on you that how you can acheive the debouncing and throttling based on your logic and requirement.there is not always mandatory to use setTimeout.

Others application of Debouncing and Throttling in Real Life

  1. In the case of window resize event, if we want to redraw the UI only when the user has fixed the size of the window, we can use debouncing.
  2. We can throttle a button click event, if we do not want the user to spam by clicking the button frequently.
  3. With Mouse move event, if we are displaying the location coordinates of the mouse pointer, it is much better to show the coordinates once the user reached the desired location. Here, we can use debouncing.

There are still many more real life application!!!!😃

I hope everyone has now a better and clear understanding of debouncing and throttling concept.

If you have any doubt or query please put in the comment section i’ll try to reply to each one and also give your valuable thoughts about the article which will definitely help me a lot to improve in further articles!! 😅

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store