Throttling and debouncing are good techniques to improve performance on your website.
Let’s imagine, that we have an event listener on mousemove or scroll and you have a callback that makes some calculations, takes much time and this function calls many times during mouse move, scroll, or other events. Of course, this situation can make your website performance really slow.
Another example, we have input for searching, and we put the listener to input event and on each input letter, we make HTTP requests. Let’s imagine, we want to find items, using the blueberry word. As soon as we type “b”, HTTP requests will fire, also “l”, also “u”, also “b” ect…Each typing letter will fire an HTTP request. But in general, we want to have just 1 HTTP call, when the word will be fully typed.
Both techniques could help with that problems and each of them works in a little bit different way and uses for different cases. So, let’s take a look at examples.
We want to create a mouse pointer, that runs after the user cursor, with a little offset from the cursor. In general, it’s an easy task, so let’s do it.
The code really simple, so let’s take a look:
We take a container (it could be any element, like a body), also I prepared a div for the pointer, added some styles (you can add any style that you want), and the heart of the logic - JS.
In JS, I just add a listener to the container. Any event listeners, pass event object, that contains much useful information and for our purpose, we have access to mouse cursor cords at the time when this callback was fired. Knowing these cords, we just add some offset and change position of our pointer.
Let’s take a look at how much time our callback will be fired. For this I will move the mouse pointer from the start left corner of my screen to the end.
Of course, it’s a not perfect measure technique, but in general, it gives understanding. In my case, as we can see it’s 55 times.
Can we decrease this function calls amount, but keep the same functionality working? Sure. Let’s introduce, the throttling technique.
Throttling set how much function can be called during a specific time. For example, call some function no more than 1 time per millisecond, like call function once per 100 milliseconds or once per 50 milliseconds.
There are many implementations of throttling and debounce you can find, and library like lodash also contains them. So, let’s pick any throttle implementation and use it for our example.
As I mentioned this is just 1 of many other implementations, if you are interested, you can find other and try to compare them, but it’s not the purpose of this article.
Now, let’s use it for our pointer.
Here, we say, that onMouseMove function will be called once 30 milliseconds. Let’s check the result:
After throttle and 30 milliseconds, the amount of our function calls is 32, instead of 55 as it was the first time. Function calls were reduced almost 2 times. You can play with the delay amount, in some cases, you can put the bigger amount, in other cases it can be a bad result and you should use a smaller delay time, so it depends on your task.
But for sure, if you have some hard calculations or HTTP requests in your callbacks, the throttle can help you with decreasing the number of function calls.
Now, let’s speak about the next task. Imagine, that we want to hide this pointer, after the user stops moving his mouse pointer, after 3 seconds. But if he stops just for 1 or 2 seconds and will continue moving we shouldn’t hide the mouse pointer.
The first solution that you can think of is that we can just add setTimeout with 3 seconds and that’s all. But, the problem with this is that it will hide the pointer after 3 seconds not depends does user move his cursor or not.
In our case, we want to make timeout of 3 seconds only after when the user stops moving his mouse. And if the user stops his mouse just for 1 or 2 seconds and after continues moving, we don’t want to hide pointer, until the user stops moving for more than 3 seconds.
Let’s see an example below:
As you can see, our mouse pointer disappears only if the user doesn’t move his mouse for more than 3 seconds.
How to make it?
Debounce - is a technique that runs function only until a certain amount of time has passed. As we can see in an example, we can delay our function for a certain amount of time, but if this time is less, our timeout is extended.
Let’s check the code:
As throttling implementation, debounce also has a lot of different implementations, so I found just one of them:
Also, I created simple hideMousePointer and showMousePointer functions:
showMousePointer I run inside onMouseMovie for that case if pointer was hidden before.
hideMousePointer I use the inside debounce function as a callback and set 3 seconds as a delay.
And yes, here in the example we combine throttling and debounce together. But it’s not required. You can use both of them independently. Instead of throttledMouseMove we can use simple mouseMove in our example, for hiding/showing result will be the same.
Another popular example of using debounce is an input field, where you type keywords for searching something, also you put input event listener, and inside the listener, you send HTTP request with the input text. But we don’t want to send HTTP for each input letter. We want to wait a small amount of time until when the user stops writing and only after sending 1 HTTP request with the whole word instead of many HTTP calls for each letter.
In general, that’s all, let’s repeat once:
Throttling is a technique that you can use when you need to run a function 1 time at each specific time interval, call the function once per 100 milliseconds or once per 50 milliseconds.
Debounce is a technique that enforces a function not to be called again until a certain amount of time has passed. For example, make HTTP request only when the user stops writing something or only after page scrolling was stopped for more than 3 seconds.
I hope that now, you have a better understanding difference between these 2 techniques and you can find their usage in your own projects.