Debouncing Simplified
Tags: javascript, react, reactnative
Published: 2023-04-08 10:40:59

---
title: Debouncing Simplified
published: true
description: Simple explaination of how debouncing work with example
tags: javascript, react, reactnative
# cover_image: https://direct_url_to_image.jpg
# Use a ratio of 100:42 for best results.
# published_at: 2023-04-07 10:27 +0000
---

Another frequently asked question in interviews these days is `Debouncing`. Debouncing is important concept used in Javascript to improve performance, prevent unnecessary wastage of resource. 

Debouncing is a mechanism in which a frequently called function is called once after some threshold time limit is reached. 
 

Lets take example - you have a search input box in UI, now you want to display result on every keyinput by user (similar to how google display search result). 

But fetching result from api on every input charater is expensive - there will be network calls, computation on backend and ui update multiple times. 

If a user want to search for `baking receipe` then it comes to total 14 characters l.e 14 api call will be made to backend, but out of 14, only 1 or 2 are enough to display relevant result. 

so on an average you make 12 api call which are not required, and if your application have 1000s of user then you multiply wasted api calls accordingly. Because resource wastage is on backend side, so 12 * 1000 api calls, this is only one search query. If your average user is making 10 search query on a day = 12 * 1000 * 10. You can see where i am going with this. 

We can avoid making unnecessary api calls by using debouncing. We design frontend UI in a way that on every character input, system wait for some time (it can be 1 second or 500 millisecond depending on your application), and during this time if there is another input then we wait again and only make api call (with complete user input) if there is no further input. 

#### Implementation - 
Consider a React application
```javascript
const HomeScreen = () => {
    const [searchQuery, setSearchQuery] = useState("")

    const triggerSearch = (e) => {
        setSearchQuery(e.target.value)
        fetchResult(e.target.value)
    }

    const fetchResult = () => {
        console.log("API called for following input :: ", input)
    }

    return (
        <div className="App">
            <label>Search for: </label>
            <input value={searchQuery} onInput={triggerSearch}/>
        </div>
    )
}
```

If we type for baking receipe the fetchResult function get called 14 times
![Bad code example](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/egv7kfylr7hsxfrekyev.png)

#### Solution : 
```javascript
const HomeScreen = () => {
    const [searchQuery, setSearchQuery] = useState("")
    const timer = useRef();

    const triggerSearch = (e) => {
        setSearchQuery(e.target.value)
        debouncedFetchResult(e.target.value)
    }

    const fetchResult = (input) => {
        console.log("API called for following input :: ", input)
    }

    const debouncedFetchResult = (input) => {
        if (timer.current) {
            // if there was any pending api call then cancel it and request new
            clearTimeout(timer.current)
        }
        
        // here we are waiting for new input for 1second. you can change accordingly
        let timeoutInstance = setTimeout(() => {
            fetchResult(input)
        },1000)

        timer.current = timeoutInstance;
    }

    return (
        <div className="App">
            <label>Search for: </label>
            <input value={searchQuery} onInput={triggerSearch}/>
        </div>
    )
}
```
Here, on every input character, we call `setTimeout` and store its reference inside state variable. And if there is any old reference available then we cancel old `setTimeout` and create a new only. 

Output - 
![Optimized Code output](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n9ahwp1d8ews2ty8rawx.png)