DEV Community

Cover image for Learn debouncing and throttling in a simple way
Ajay Kumar Verma
Ajay Kumar Verma

Posted on • Originally published at weekendtutorial.com

Learn debouncing and throttling in a simple way

If you’re a frontend developer you must have handled the various events like button clicking, form submit, and window scroll events, etc through event handlers.

Some events are lightweight and don’t interfere with the UX behavior but some are just the opposite of it, for instance, it is strongly advised to not attach any event handler on the window scroll event or resize event.

The reason is in comparison to other events, depending on the browser and the device the scroll event can fire a lot, which places lots of scroll callbacks into the callback queue and call stack. Thus, the page becomes unresponsive and not scrollable.

The two widely known techniques that solve the above problem are —

  1. Debouncing
  2. Throttling

Let’s see how debouncing and throttling helps to solve the above problem and other use cases also.


What is Debouncing?

Debounce technique can be understood by a timer. When the button is pressed the timer started. If the button is pressed again before the timer expires, the timer is reset. This ensures that the button can only be registered as being pressed once per debounce period.

debounce - grouping the multiple calls to one

Let me take another example, the elevator

Imagine you’re in an elevator and the door is about to close. But, just before that another person comes in, the elevator door opens again. Now it waits for another person for a specific time and if no one comes door is closed. So, we see the timer reset on the new call and “group” multiple sequential calls into a single one.

Other use cases  — 

  • SearchBar 
  • Autocomplete feature
  • Auto-saving user input
  • the clicking of a button that makes API calls

Implementation of debouncing

Let’s create an index.html file having an input field.

On keypress, we suppose to call an API. Let’s handle this behaviour by debouncing.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Js-Perf</title>
</head>
<body>
<h2>Debounce method</h2>
<input type="text" id="search" />
<h2>Throttle Method</h2>
<button id="pistol">Shoot</button>
<script src="debounce.js"></script>
<script src="throttle.js"></script>
</body>
</html>
view raw perf.html hosted with ❤ by GitHub

and debounce.js –

const searchEl = document.getElementById('search');
let called = 0;
const searchHandler = function () {
called += 1;
console.log(`called ${called} time`);
};
const debounceHandler = (func, delay) => {
let timer;
return function () {
let context = this, args = arguments;
clearTimeout(timer); // new req pops in, reset and start the timer again
timer = setTimeout(function () { // start a new timer again
func.apply(context, args);
}, delay);
};
};
searchEl.addEventListener('keypress', debounceHandler(searchHandler, 250));
view raw debounce.js hosted with ❤ by GitHub

if you check the console, you will find that the no. of time the event handler called is way less than the actual input size. And thats the big performance boost!


What is Throttling?

Throttling technique can be understood by a counter. When the button is pressed the counter is incremented. Now till the counter reaches a certain threshold all button pressing is ignored. This limits the number of times the button can be registered as being pressed in a given period of time.

throttle - calling func at a fixed interval

Other use cases — 

  1. Shooting game — Pistol takes 1 sec time between each shot but the user clicks the mouse button multiple times.
  2. Infinite scrolling

Implementation of throttling

Let’s update the above index.html file with a button.

On the button click, we suppose to call an API. Let’s handle this behaviour by throttling.

throttling.js –

const pistolEl = document.getElementById('pistol');
let fireCount = 0;
const shoot = function () {
fireCount += 1;
console.log(`pistol fired ${fireCount} time`);
};
const throttleHandler = (func, delay) => {
let inThrottle;
return function () {
let context = this, args = arguments;
if (!inThrottle) { // for first time it will always go inside if
func.apply(context, args); // call the func
inThrottle = true; // set the timer true to avoid all req till timer is alive
setTimeout(function () { // start a timer
inThrottle = false;
}, delay);
}
};
};
pistolEl.addEventListener('click', throttleHandler(shoot, 500));
view raw throttle.js hosted with ❤ by GitHub

We can see that button handler will be called at each 500ms and all the button click within this window is ignored.


As we have seen the performance benefits of using the debounce and throttle, based on your use case, you can use it in your code base.

Note:

Underscore and Lodash.js libraries also have the debounce and throttle method, you can check that as well.

If you want to know how to create a javascript object, please check –

https://weekendtutorial.com/what-is-object-in-javascript-and-how-to-create-it/

https://weekendtutorial.com/how-to-implement-binary-heap-in-javascript-in-2022/

References

Twitter scrolling issue in 2011

Image of Datadog

The Essential Toolkit for Front-end Developers

Take a user-centric approach to front-end monitoring that evolves alongside increasingly complex frameworks and single-page applications.

Get The Kit

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay