Throttling and Debouncing. Avoiding unnecessary API calls.
Tags: javascript, webdev, beginners, codenewbie
Published: 2020-04-03 18:46:20

## The problem

There are sometimes that we need to perform actions on certain events controlled by the user. This can be the case of events like <code>click</code>, <code>onPress</code>, <code>mouseMove</code>, etc.
A function runs every time any of those events are triggered, and this can happen more time that is necessary, leading to performances issue.
Imagine a type-ahead functionality in a search bar where we have to retrieve the results from an API. If the user types a four-letter word, it calls the API 4 times, but only the last one is essential.
So, how can we prevent those unnecessary calls and potential API calls?

## What is Throttling and Debouncing

### Throttling

Throttling is a pattern that we can limit the times it fires an event. So, no matter how many times the user can trigger this, it executes only once in a specific time interval.
This technique can be helpful in a case we know the user can abuse clicking a button. We can just let the event trigger for the first time and not let rerun until x milliseconds passed.

### Debouncing

Just like Throttling, Debounce limits the times an event fires. The difference is with this technique, no matter how many times the user fires the event, the function will be executed only after a specific time after the last fired.
It means that in the search bar example, the user can type all the four letters. Still, only x milliseconds after the last <code>onPress()</code> call was triggered, the function executes.

## Throttling in javascript

Let's see some code. In this case, we will let the user execute a function only every half a second.
{% codesandbox throttling-example-8nwzp %}

```javascript
let timeout;
const throttle = (func, limit) => {
  if (!timeout) {
    func();
    timeout = setTimeout(function() {
      timeout = undefined;
    }, limit);
  }
};
```
Examining the code above:

1. The <code>throttle</code> function receives 2 parameters. First, the function we want to perform and second the interval time expressed in milliseconds.
2. When <code>throttle</code> executes for the first time, <code>timeout</code> is undefined as is not initialized. Next, we execute the parameter function and schedule a <code>setTimeout</code> that will set <code>timeout</code> to undefined after the <code>limit</code> milliseconds.
3. As we are checking <code>timeout</code>, the function won't be executed after the <code>setTimeout</code> and <code>timeout</code> is undefined again. This ensure the function is called only once in an interval. 

## Debouncing in javascript

For this example, we will have a search box. Every user input will trigger an event, but the function will execute after a delay of 0.2 seconds.
{% codesandbox debouncing-example-drfir %}

```javascript
let timeout;
var debounce = function(func, delay) {
  clearTimeout(timeout);

  timeout = setTimeout(func, delay);
};
```

1. First time <code>debounce</code> function is called, <code>timeout<code/> is undefined so <code>clearTimeout</code> does nothing. 
2. We schedule a <code>setTimout<code> to execute the function after a certain <code>delay</code>
3. If the function is not called again during that period, <code>clearTimeout</code> won't end the execution of <code>timeout</code> and after <code>delay</code>, <code>func</code> executes. 

## When to use each one?
* As one of the examples, we can use <code>debounce</code> to control the times an API call to search results due to user input in a case of type-ahead functionality.
* Also if we have a button or a RefreshControl to force sync data we can limit the times it can be executed using <code>throttle</code>
* <code>debounce</code> can also be useful in case we need to wait for the user to stop scrolling to the desired place, finish resizing a windows o to capture the last position of a <code>mousemove</code>.

## Libraries to the rescue
As you can see, these two techniques are very helpful and they are very utilized in a lot of projects. So is not strange that there are some libraries which implement them. Here are some of them:

- **lodash.js**: It comes with [<code>debounce</code>](https://lodash.com/docs/#debounce) and [<code>throttle</code>](https://lodash.com/docs/#throttle) built-in. 
```javascript
// Debounce
searchInput.addEventListener("input", _.debounce(search, 200));

// Throttle
button.addEventListener("click", _.throttle(callToAPI, 500);
});
```

- **jQuery**: There is a [project](http://benalman.com/projects/jquery-throttle-debounce-plugin/) to help us.

```javascript
// Debounce
$('#searchInput#').keyup($.debounce(200, search));

// Throttle
$('#button#').click($.throttle(500, callToAPI));
```

- **throttle-debounce**: can be found in npm [here](https://www.npmjs.com/package/throttle-debounce)

```javascript
// Debounce
searchInput.addEventListener("input", debounce(200, search));

// Throttle
button.addEventListener("click", throttle(500, callToAPI);
});
```

## Conclusion
I hope this helps you to at least be aware of these two great techniques to avoid extra function executions. 
Please give me your thoughts in the comments section. I'm always open to suggestions and tips to getting better in this new adventure for me writing this kind of post.
Thanks for reading!.