DEV Community

Pedro Filho
Pedro Filho

Posted on

Understanding Debouncing and Throttling using Javascript

I can't remember how many times I had to use one of these debouncing or throttling, they are a necessity for any app that is used in real life.

So, let's start with a debounce function. A debounce function is something I usually use for things like autocompletes, and that's how I'll explain it to you!

Imagine that you want to build an address auto-complete functionality for your checkout, let's see how it would work without a debounce function:

<!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>Debounce and Throttle</title>
  </head>
  <body>
    <input id="debounce" type="text" placeholder="debounce" />

    <script>
      document.getElementById("debounce").addEventListener(
        "keydown",
        (e) => {
          console.log(e.target.value);
        }
      );
    </script>
  </body>
</html>
Enter fullscreen mode Exit fullscreen mode

Very simple, right? But what happens if your service charges per call, or if you're running it on a server and you don't want to make your IT team crying? Well, that's where the debounce function shines.

<!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>Debounce and Throttle</title>
  </head>
  <body>
    <input id="debounce" type="text" placeholder="debounce" />

    <script>
      const debounce = (func, wait) => {
        let timeout;

        return (...args) => {
          if (timeout) clearTimeout(timeout);

          timeout = setTimeout(() => func(...args), wait);
        };
      };

      document.getElementById("debounce").addEventListener(
        "keydown",
        debounce((e) => {
          console.log(e.target.value);
        }, 1000)
      );
    </script>
  </body>
</html>
Enter fullscreen mode Exit fullscreen mode

Now, it'll only run after the user stops typing for 1 second, everyone is happy!

But let's say you have a limitation that you can only call your API 1 time every 2 seconds. That's the job for the throttler function! Let's see how it would be implemented without it:

<!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>Debounce and Throttle</title>
  </head>
  <body>
    <button type="button" id="throttle">throttle</button>

    <script>

      document.getElementById("throttle").addEventListener(
        "click",
        () => {
          console.log("clicked");
        }
      );
    </script>
  </body>
</html>
Enter fullscreen mode Exit fullscreen mode

Well, an anxious user can break your application! Let's see how we can prevent that with a throttler function:

<!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>Debounce and Throttle</title>
  </head>
  <body>
    <button type="button" id="throttle">throttle</button>

    <script>
      const throttle = (func, wait) => {
        let lastTime = 0;

        return (...args) => {
          const now = Date.now();

          if (now - lastTime >= wait) {
            func(...args);

            lastTime = now;
          }
        };
      };

      document.getElementById("throttle").addEventListener(
        "click",
        throttle(() => {
          console.log("clicked");
        }, 2000)
      );
    </script>
  </body>
</html>
Enter fullscreen mode Exit fullscreen mode

Awesome, right? These functions can really help you with some real life issues!

Discussion (0)