# Debouncing vs Throttling

In this article, we will learn about debouncing and throttling when to use and when to use them.

Both of these techniques are used to improve the performance optimization of web pages.

let's Take an example using a general approach

## General Approach

```javascript
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="style.css">
</head>

<body>
    <input type="text" name="search" id="search" placeholder="Search">
    <script src="index.js" type="text/javascript"></script>
</body>
</html>
```

```javascript
//Case 1 : genral approach
let textField = document.querySelector('#search');
let count=0
textField.addEventListener('input', (event) => {
console.log(`fires times: ${count++} value:  ${event.target.value}`)
})
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1684754967414/0cfb6608-415b-4352-b536-697db73e185f.jpeg align="center")

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1684754974662/7c8a520e-afa6-4338-8a9f-d64cbe54f1ae.jpeg align="center")

In the above example, we will attach a listener to the keypress event. Every time you enter any keyword it calls a function.

The above technique is not optimal and leads to unnecessary function calls that stall the performance of the web page.

Let's explain with respect to the ecommerce website where we are searching for a desired item.

Suppose the user tries to search for an `"apple watch"` now each when user will press `"a"` then this fetch request will be triggered and it will return all the data that have `"a"` in it then the user will press `"p"` so now again this fetch API call will be triggered and it will return all the results will which has `"ap"` in it and this way this API will be triggered each time when the user is pressing any key so for `"apple watch"` it will be called 10 times.

Now the arises how can we reduce the number of times this fetch API  
called. To solve this problem there are two technique that are debouncing & throttling.

To optimize it further we will use debouncing & throttling.

Now let's explore them one by one:

## **Debouncing Technique**

> ***In the debouncing technique, no matter how many times the user fires the event, the attached function will be executed only after the specified time once the user stops firing the event.***

Let's change our code

```javascript
const debounce = (func, delay) => {
  let timerId;
  return function (...args) {
      clearTimeout(timerId)
      timerId = setTimeout(() => func(...args), delay)
  };
};
let count=0;
let handleInput= debounce((event) => {
  console.log(`fires times:${count++} ${event.target.value}`)
},1000)


let textField = document.querySelector('#search');
textField.addEventListener('input', handleInput);
```

The debounce() function forces a function to wait a certain amount of time before running again. The function is built to limit the number of times a function is called.

In this case, we wait for the user to stop typing for a few seconds before calling our function. thus, on every keystroke, we wait for some seconds before giving a response.

### **How it works:**

1. The `debounce` function takes two parameters: `func` (the function to be debounced) and `delay` (the duration of inactivity required before executing the function).
    
2. Inside the `debounce` function, a `timerId` variable is declared to keep track of the setTimeout timer.
    
3. The returned function is a closure that wraps the original function `func`.
    
4. Whenever the returned function is called (in this case, when the 'input' event is triggered), it clears the previous setTimeout timer using `clearTimeout`.
    
5. It then sets a new setTimeout timer, which delays the execution of `func` by the specified `delay`.
    
6. The `func` is executed inside the setTimeout callback, passing any provided arguments using the spread operator `...args`.
    
7. This ensures that `func` is only executed after the specified `delay` of inactivity.
    

the `handleInput` function is the debounced function that will be executed when the 'input' event is triggered on the `textField` element. The `console.log` statement inside `handleInput` will display the number of times the event is fired and the value of the input field.

By debouncing the input event, the `handleInput` function will only be executed after a 1 second period of inactivity, effectively reducing the number of function calls and improving performance, especially in scenarios where the user is typing rapidly.

## **Throttling Technique**

> **Throttling is a technique used to limit the rate at which a function is executed. It ensures that the function is called at a regular interval, regardless *no matter how many times the user fires the event.***

Let's change our code

```javascript
//Case 3: With Throttling
const throttle = (func, delay) => {
    let toThrottle = false;
    return function (...args) {
        if (!toThrottle) {
            toThrottle = true;
            func(...args)
            setTimeout(() => {
                toThrottle = false
            }, delay);
        }
    };
};

let count=0;
let handleInput= throttle((event) => {
  console.log(`fires times:${count++} ${event.target.value}`)
},1000)


let textField = document.querySelector('#search');
textField.addEventListener('input', handleInput);
```

Throttling is used to call a function after every millisecond or a particular interval of time only the first click is executed immediately.

`throttle` function takes an existing expensive function & delay limit and returns a better expensive function which is called only after a certain delay limit.

### **How it works:**

1. The throttle function takes two parameters: `func` (the function to be throttled) and `delay` (the minimum time between function calls).
    
2. Inside the throttle function, a `toThrottle` flag is declared and set to `false`. This flag keeps track of whether the function is currently being throttled.
    
3. The throttle function returns a new function, which is the throttled version of the original function. This function is a closure that has access to the `toThrottle` flag and the parameters passed to the throttled function.
    
4. When the throttled function is called, it first checks the `toThrottle` flag. If it's `false`, indicating that the function is not currently being throttled, it proceeds with the execution.
    
5. Inside the if statement, `toThrottle` is set to `true`, indicating that the function is now being throttled.
    
6. The original `func` is executed with the provided arguments using the spread operator `...args`.
    
7. After executing `func`, a setTimeout timer is set with a duration equal to the specified `delay`.
    
8. Inside the setTimeout callback, the `toThrottle` flag is set back to `false`, allowing the function to be executed again.
    

the throttled `handleInput` function is attached as an event listener to the `input` event of a text field (`#search`). Each time the event is triggered, the function is called at most once every 1000 milliseconds (1 second), effectively throttling the input event handling.
