DEV Community

loading...
Cover image for JavaScript - debounce vs throttle ⏱

JavaScript - debounce vs throttle ⏱

Yash Soni
He is a Software Engineer, passionate about digital products, loves reading and writing tech blogs, Apple fanboy, crazy about discussing possibilities… ❤ 😇
・3 min read

There's been a lot of confusion around what is debouncing and throttling, where to use it, and how it exactly works.

We are going to demystify all of the above in the simplest possible way through this article.

It is important to know both of these, it will make our lives easier in certain scenarios. (Bonus: This is a common interview question too) 🥳


Simply put,
Throttling is a way to limit the number of times a function can be called. Perform a function, then drop all the function calls until a certain period of time,

Debouncing is a way to delay the execution of a function to a later period until there is some ongoing action.

These both might seem confusing, overlapping, almost the same thing - but they are not! We will sort this out.

There's no better way to learn something than learning by example. 👩‍💻👨‍💻


Throttling:

Imagine there's a button "Fetch Quote". When you click it, it triggers an asynchronous API call to fetch the quote and render it on the screen.

Now, what will happen if some nutjob keeps clicking it furiously - like a million clicks till his/her fingers give up. 😑

In that case, without any controlling mechanism, it will trigger a million API calls (intentionally over-exaggerated!)
This would cause a performance drop.

You can avoid this if you had some kind of click rate-limiter in place.

Throttle swaggers-in 😎

How does it work?

Alt Text

Here's the CodePen for the "Fetch Quote" example. Play around this a bit.


Debouncing:

Remember how the search-suggestions work? Like, when you start typing into the Google search bar it keeps on updating its suggestion list.

These suggestions are actually brought from an API call. So, the question is, should you make a fresh API call every time the text changes in the input box?

No, right? That would be super-bad for Google. Imagine you type "How to write better JavaScript" - 30 characters itself, leading to 30 API calls. Now imagine, millions and billions of Googlers around the world typing their queries every second - BAMMMMM!!! 💥

So how do you handle this?

Before we answer that, do we really need to make an API call if the user is still typing? No. We should wait till the user has halted typing for at least some amount of time before we make an API call.

This can be achieved using, yeah you guessed it right, Debouncing.

As we stated earlier, debouncing is a way to delay the execution of a function to a later period until there is some ongoing action.

The following CodePen illustrates exactly the same.


Bonus part: Understanding the nitty-gritty 💸

Let's see the function definitions of debounce and throttle in detail.

Throttle

const throttle = (func, delay) => { 
  let toThrottle = false;
  return function() { 
    if(!toThrottle) {
      toThrottle = true;
      func.apply(this,arguments)
      setTimeout(() => {
        toThrottle = false
      }, delay);
    }
  }; 
};

Debounce

const debounce = (func, delay) => { 
  let timerId; 
  return function() { 
    clearTimeout(timerId) 
    timerId = setTimeout(() => func.apply(this,arguments), delay)
  }; 
};

From the definition, we can clearly see that

  • Throttle allows execution immediately if the toThrottle flag is false. After the execution, this function will not be called until the delay period has lapsed.
  • Debounce postpones execution until there is no input change for the delay period of time. If a change occurs, cancel the previously scheduled execution and create a new schedule.

P.S. This article requires a prior understanding of closures, this, call, apply in JavaScript. I'm dropping a recommended reading list below to help sharpen this.

  1. Understanding Bind, Call, Apply in JavaScript
  2. Understanding setTimeout
  3. Understanding Closures

Share this article if you liked it!
Follow on Twitter for more posts, quizzes and articles on Tech. 😃👋

Discussion (5)

Collapse
assurestudios profile image
John Moore

Can somebody please explain in baby terms why func.apply(this, arguments) is needed instead of just func()

Collapse
iyashsoni profile image
Yash Soni Author

Hi John, we use apply when we need to pass an explicit this context to the function. You may want to check the following examples: taniarascia.com/this-bind-call-app...

Collapse
sebring profile image
J. G. Sebring • Edited

Well explained and kept minimalistic with great examples, showing there is really no need for rx just to throttle/debounce some buttons.

Collapse
iyashsoni profile image
Yash Soni Author

That was exactly the aim. We rely so much on the libraries that sometimes we don’t even care about learning how it actually works, let alone raising question on whether the library is really needed in the first place.

Collapse
sebring profile image
J. G. Sebring

Yes indeed, and before you know it the bloat is real. So many times I've seen _ and $ added just for some trivial task used in one function they've added. Where most frameworks already have similar functions or better/preferred ways to do things (DOM-manipulation being the classic example)