Debouncing in Javascript
Tags: javascript, webdev, tutorial, performance
Published: 2020-11-30 15:59:13

In today's world, it's of utmost necessity to have an application that can scale, be robust, and be performant. One of the ways to improve the efficiency of the applications is by using the concept called **Debouncing**

In debouncing, we limit the calls for 'N' time period and thereby reducing the calls to api's,requests to fetch the data. Though there are various libraries such as *loadlash* and *underscore JS*, we would be implementing the basic version to understand what goes behind the scene. Please do not use this version for the production level development.

We would be creating a div block that would help us to perform the *mousemove* event & maintaining the count of the event without the debounce method and another one with the debounce method.

`index.html`
```html
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <!-- CSS only -->
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-alpha3/dist/css/bootstrap.min.css" rel="stylesheet"
        integrity="sha384-CuOF+2SnTUfTwSZjCXf01h7uYhfOBuxIhGKPbfEJ3+FqH/s6cIFN9bGr1HmAg4fQ" crossorigin="anonymous">
    <link rel="stylesheet" href="./css/style.css" />
    <!-- JS -->
    <script src="./app.js"></script>
    <title>Debounce Tuts</title>
</head>

<body>
    <div class="container">
        <h2>Debounce Tuts</h2>
        <div class="jumbotron">
            <h4>Raw Count: <p id="rawResult"></p>
            </h4>
            <h4>Debounce count: <p id="debounceResult"></p>
            </h4>
            <div id="card">
               <!-- Space for hovering -->
            </div>
        </div>
    </div>
</body>

<script>
    var rawMoves = 0,
        debounceMoves = 0;
    var divById = document.getElementById("card");

    //for raw count
    divById.addEventListener('mousemove', function () {
        var resultRaw = document.getElementById("rawResult");
        rawMoves++;
        resultRaw.innerHTML = rawMoves.toString();
    });

    //for debounce count
    divById.addEventListener('mousemove', debounce(function () {
        var resultDebounce = document.getElementById("debounceResult");
        debounceMoves++;
        resultDebounce.innerHTML = debounceMoves.toString();
    }, 500));
</script>

</html>
```

We would be adding basic css for having a better UI
`style.css`
```css
*{
    padding: 10px;
}
#card {
    width: 100px;
    height: 100px;
    background-color: #1b9dc4;
    border-radius: 15px;
}

.jumbotron {
    padding: 2rem 1rem;
    margin-bottom: 2rem;
    background-color: #e9ecef;
    border-radius: .3rem;
}
```
`app.js`
```javascript
function debounce(callback, delay) {
  let isBounce
  return function () {
    clearTimeout(isBounce);
    isBounce = setTimeout(() => callback(), delay);
  }
}
```
Debounce is a higher order function, hence debounce function returns another function, which would be executed after the *delay* from the moment the event has been triggered. 

The concept of [*closure*](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures) comes into the picture for maintaining and associating the delays to *isBounce*. *clearTimeout()* would clear *delay* set by the method *setTimeout()* as and when the event is triggered. This would wait for *delay* amount of time from the last event triggered and then perform the *callback* passed to it.


Cheers :v::v:, we are done with the implementation. Now we can run the index.html on the browser. I must say that there are many ways of implementing this that would be more performant efficient but my intention is to help a beginner in understanding the basics of debounce and hence opted to a simpler version of the code. You would be using this primarily to improve the *suggestive text* and *content-loading* functionality.