Throttling and Debouncing in JavaScript

Objective

To understand throttling and debouncing process in JavaScript, with an example.

Pre-requisites

  • An initial JS project structure on StackBlitz.

Pertaining Repository

The code, with all the commits, is available in this repository.

You can also view the project in this Stackblitz Project.

Lets start …

Section #1

Why Throttling or Debouncing is needed?

Imagine that a computer program is calling a function, let’s say someFunction(), at least every 50ms (we’ll call this function-call-stream from now on). So, if that program runs for 10seconds, then the function someFunction() would be called at most 200 times.

It is certainly not wanted, as it affects the performance of the system and it’s not an optimised way of handling it. To overcome this, Throttling or Debouncing is needed.

To give an idea, Throttling or Debouncing act as a filtering layer between the computer program and someFunction(), which decides when to call someFunction() and when not.

What is Throttling in JavaScript?

Throttling is a technique in which someFunction() is called only once in a specified time interval until the function-call-stream is over.

So, for the given case above, if we specify the time interval to be 500ms in which someFunction() is called only once, then the total number of times someFunction() would be called is 19, a huge improvement than 200 times!!

The graphical representation is like this —

Figure 1.1 : Graphical Representation of Throttling

What is Debouncing in JavaScript?

Debouncing is a technique in which someFunction() is called after certain time-interval of function-call-stream-ending.

So, if function-call-stream ends in 1000ms and the specified time-interval is 350ms, then someFunction() would be called after 1350ms . The graphical representation is like this —

Figure 1.2 : Graphical Representation of Debouncing

And if before the completion of 350ms, the function-call-stream starts again, then someFunction() would not be called until again function-call-stream ends and specified time-interval is passed.

Section #2

Let’s implement throttling and debouncing.

But before that, we will implement the naive case, i.e without throttling or debouncing.

Naive Case

In the basic JS project on StackBlitz, remove all the code of index.html & index.js and put the following code

Gist #2.1 : Naive form

The code is self-explanatory, that we have introduced a button, and attached a click event listener with it.

Now, clicking on the button n number of times would result in ‘Naive Case’ to be printed that many times.

This may not seem problematic. But what if you add the following code at the bottom of index.js

let interval = setInterval(() => {
btnRef.click();
}, 50);
setTimeout(() => {
clearInterval(interval);
}, 10000);

You will notice that performance of the browser is hugely impacted. This is where throttling or debouncing come as a saviour.

Throttling implementation

Look at the code below pertaining to throttling —

Gist #2.2 : Throttling

In the event listener method we execute a throttle method, with reference of actual method to be executed and the interval as its arguments. This returns another method, which executes the actual method after a delay (set using setTimeout) with the help of a timer variable. Timer variable is used to block other method calls which falls in that interval.

The result is that click handler of the button is called only 19 times.

(Note : It may seem that throttling executes the method only at the trailing edge of the interval, but it can be also executed at the leading edge of the interval. Just few modifications in code is needed. )

Debouncing implementation

Look at the code below pertaining to debouncing —

Gist #2.3 : Debouncing

In debouncing what is changed from throttling is that —

  • the timer variable, rather than blocking the method calls, just resets itself , using clearTimeout, whenever the new method call arrive.

The result is howsoever times button is clicked, the click handler is executed only when 2s has passed after the function-call-stream ends. You can try it on the project link.

Conclusion

In this article, we understood about basics of throttling and debouncing.

Web Developer