Table of contents
1.
Introduction
2.
Applications of Debouncing
3.
Simple Implementation of debounce
4.
Implementation of search with custom debounce
5.
FAQs
5.1.
What do you mean by debounce function?
5.2.
What are the advantages of using debounce function?
5.3.
What are the two important tasks handled by the search with debounce function?
5.4.
How many parameters does a simple debounce function have? Name them.
5.5.
How a simple debounce function acts in terms of programming?
6.
Conclusion
Last Updated: Mar 27, 2024
Easy

Implement Search With Custom Debounce Function

Author Aditya Kumar
0 upvote
Career growth poll
Do you think IIT Guwahati certified course can help you in your career?

Introduction

One of the most essential parts of the development process is “Performance”. There are approaches in JavaScript that can assist us with this, particularly how to manage event behaviour. However, the implementation changes when you try to utilise them with a different framework/library.

Debouncing in Javascript is a technique for improving browser speed during lengthy calculations. If this method is called frequently, it may damage the performance of our web app. Debouncing is a programming technique for reducing the frequency with which a time-consuming process fires. In other words, it restricts the frequency with which functions are called.

Applications of Debouncing

Here are the applications of debounce function which is mentioned below:

  • Debouncing can be used when searching is done, such as when a user types in a search box and the server returns the results. After the user has finished typing, we may access the server API (after an inevitable delay). If every update results in a frequent server API visit, our server's performance will suffer greatly.
  • Debouncing is also used on content-loading websites like Facebook and Twitter, where the user keeps scrolling. Since there are so many movies and pictures in these instances, it may impact performance if the scroll event is thrown too frequently. As a result, debouncing must be used in the scroll event.

Simple Implementation of debounce

This is the simple implementation of debounce function for a better understanding:

main.html

<html>
    <head>
        <title>Debounce implementation</title>
        <link href="https://fonts.googleapis.com/css2?family=Jua&family=Roboto:wght@300&display=swap" rel="stylesheet"> 
        <link rel="stylesheet" href="./assets/css/main.css">
    </head>
    <body>
        <main>
            <div class="card blue">
                <h1>Simple implementation of Debounce</h1>
                <input type="text" onkeyup="processChanges()" />
                <button onclick="processChanges()">Hit me</button>
            </div>
        </main>
    </body>
</html>

main.css

/* layout relevant styles */
html, body
width: 100%
height: 100%
margin: 0

main
display: grid
height: 100%
grid-template-columns: auto 33% auto
grid-template-rows: auto auto auto

.card
display: grid
grid-template-columns: 100%
grid-column: 2
grid-row: 2

/* other styles */
.card
padding: 50px
color: #fff
border-radius: 20px
box-sizing: border-box
font-family: Roboto, sans-serif
background: rgb(0,174,239)
background: linear-gradient(135deg, rgba(0,174,239,1) 20%, rgba(45,56,138,1) 100%)

h1
margin: 0
font-size: 3rem
font-weight: lighter
text-align: center

input
width: auto
height: 50px
border-radius: 25px
border: 0
line-height: 50px
padding: 0 20px
font-size: 1.5rem
font-family: Roboto, sans-serif
outline: none

button
width: 240px
height: 50px
border-radius: 25px
border: 2px solid #fff
line-height: 50px
text-align: center
font-size: 1.5rem
color: #fff
text-decoration: none
margin-top: 10px
position: relative
box-sizing: border-box
justify-self: center
background: transparent
cursor: pointer
font-family: Roboto, sans-serif
outline: none

&:hover
background: #ffffff
color: #000
&::after
right: 10px

&::after
content: ">"
font-family: "Jua"
position: absolute
right: 15px
transition: right 1s ease

a, a:hover
transition: all 0.3s ease

main.js

function debounce(func, timeout = 300){
  let timer;
  return (...args) => {
    clearTimeout(timer);
    timer = setTimeout(() => { func.apply(this, args); }, timeout);
  };
}
  
function saveInput(){
  console.log('Saving data');
}

const processChanges = debounce(() => saveInput());
You can also try this code with Online Javascript Compiler
Run Code

Output

It may be applied to the following input:

<input type="text" onkeyup="processChange()" />

Alternatively, a button:

<button onclick="processChange()">Hit me</button>

Alternatively, consider a window event:

window.addEventListener("scroll", processChange);
You can also try this code with Online Javascript Compiler
Run Code

Also, on other elements, such as an essential JS function.

So, what's going on here? The debounce is a unique function that performs two functions:

  • The timer variable is given a scope.
  • You may schedule your function to run at a specific time.

Let's look at the first use case with text input to see how this works.

The debounce initially resets the timer using clearTimeout when a visitor writes the first letter and releases the key (timer). The step is not required at this time because nothing is scheduled. The given method, saveInput(), is expected to be called in 300 milliseconds.

However, if the visitor continues to type, each essential release will re-trigger the debounce. Every invocation must reset the timer cancel the previous plans with saveInput(), and reschedule it for a new time—300 milliseconds in the future. This will continue as long as the visitor maintains the keystrokes within 300 milliseconds.

Because the previous schedule will not be cleared, saveInput() will be invoked at some point.

Implementation of search with custom debounce

We'll show you how to utilise debouncing to create a real-time search feature in your React app, where the search results refresh in real-time as the user inputs.

What exactly are we constructing?

We'll make a search page with a search box (where the user fills in their query) and a list of the search results (updates in real-time as the user types).

This is how it looks.

This is inefficient in terms of speed since if the user types 50 or 100 characters in the input box, 50 to 100 API requests will be made.

Let's create a debounce function. It will provide us with a new function (an optimised function). The reasoning behind this method is that data will be retrieved from the API only if the duration between two keypress events is higher than 500 milliseconds. Only the handleChange function will be invoked if the delay is more than 500 milliseconds.

To correct our context, we'll utilise the apply function. We should clear this setTimeout if the duration between these two keystroke events is less than 500 milliseconds (timer variable). Instead of using the handleChange method directly, we'll utilise this optimised function (returned by the debounce function).

const debounce = (func) => {
    let timer;
    return function (...args) {
      const context = this;
      if (timer) clearTimeout(timer);
      timer = setTimeout(() => {
        timer = null;
        func.apply(context, args);
      }, 500);
    };
  };
const handleChange = (value) => {
    fetch(`https://demo.dataverse.org/api/search?q=${value}`)
      .then((res) => res.json())
      .then((json) => setSuggestions(json.data.items));
  };

You can also try this code with Online Javascript Compiler
Run Code

Now we can use Chrome's network tab to look at the results and enter them in. Only one or two times is the call made when all of the results have been fully typed into the input area.

 

On each rendering, our search with custom debounce will return a new function. We don't want that. Therefore we'll utilise the useCallBack hook instead. It will offer us a callback that has been memorised.

const optimizedFn = useCallback(debounce(handleChange), []);
You can also try this code with Online Javascript Compiler
Run Code

Here is the code to implement it.

import React, { useCallback, useState } from "react";

const DebounceSrcatch = () => {
  const [suggestions, setSuggestions] = useState("");

  const debounce = (func) => {
    let timer;
    return function (...args) {
      const context = this;
      if (timer) clearTimeout(timer);
      timer = setTimeout(() => {
        timer = null;
        func.apply(context, args);
      }, 500);
    };
  };

  const handleChange = (value) => {
    fetch(`https://demo.dataverse.org/api/search?q=${value}`)
      .then((res) => res.json())
      .then((json) => setSuggestions(json.data.items));
  };

  const optimizedFn = useCallback(debounce(handleChange), []);

  return (
    <>
      <h2 style={{ textAlign: "center" }}>Debouncing in React JS</h2>

      <input
        type="text"
        className="search"
        placeholder="Enter something here..."
        onChange={(e) => optimizedFn(e.target.value)}
      />

      {suggestions.length > 0 && (
        <div className="autocomplete">
          {suggestions.map((el, i) => (
            <div key={i} className="autocompleteItems">
              <span>{el.name}</span>
            </div>
          ))}
        </div>
      )}
    </>
  );
};

export default DebounceSrcatch;
You can also try this code with Online Javascript Compiler
Run Code

Lodash is another approach to accomplish debouncing. We may utilise Lodash's debounce technique to restrict the pace at which the handleChange function is executed. Simply use the debounce method to encapsulate the callback function and specify the length of time between two events. Now, if you go back to Chrome and test it, it still works.

import { debounce } from "lodash";
const handleChangeWithLib = debounce((value) => {
    fetch(`https://demo.dataverse.org/api/search?q=${value}`)
      .then((res) => res.json())
      .then((json) => setSuggestions(json.data.items));
  }, 500);
You can also try this code with Online Javascript Compiler
Run Code

We may also use another npm package named react-debounce-input. In comparison to the other two approaches, this is the easiest. Instead of using the regular input tag, use DebounceInput from the react-debounce-input package. As well as providing a delay property. Returning to Chrome and checking again, we see that calls are still made only when we fully type results.

<DebounceInput
     minLength={2}
     className="search"
     placeholder="Enter something here..."
     debounceTimeout={500}
     onChange={e => handleChange(e.target.value)} />
You can also try this code with Online Javascript Compiler
Run Code

Check out this problem - Count Ways To Reach The Nth Stair 

FAQs

What do you mean by debounce function?

The debounce() method makes a function wait for a set period before resuming its execution. The function is designed to limit how many times a function can be called. The function Send Request() is debounced. Regardless matter how many times the user hits the button, requests are only delivered at certain intervals.

What are the advantages of using debounce function?

The debounce function prevents the keyup event from being processed until the user has ceased typing for a certain length of time. This eliminates the requirement for your UI code to process each event and substantially minimises the number of API calls made to your server.

What are the two important tasks handled by the search with debounce function?

The debounce is a unique function that performs two tasks:

  • The timer variable is given a scope.
  • You may schedule your function to run at a certain time.

How many parameters does a simple debounce function have? Name them.

Function, time and immediate are the three input parameters for a basic debounce function.

How a simple debounce function acts in terms of programming?

A basic debounce function acts as a flag; if supplied as truthy, the function will be executed quickly.

Conclusion

In this article, we have discussed the implementation of search with custom debounce function. We have also discussed what is debouncing and how to improve performance. So basically, the debounce() method makes a function wait for a set time before resuming its execution. The function is designed to limit how many times a function can be called. The function Send Request() is debounced. Regardless matter how many times the user hits the button, requests are only delivered at certain intervals.

We hope that this blog has helped you enhance your knowledge regarding memoization in Javascript. If you want to learn more, check out our article on Memoization in JavaScriptDebounce and Throttle, and Explain "this" keyword and Scope of this in Javascript Arrow Functions.

Refer to our guided paths on Coding Ninjas Studio to learn more about DSA, Competitive Programming, JavaScript, System Design, etc. Enroll in our courses and refer to the mock test and problems available; look at the Top 150 Interview Puzzles interview experiences and interview bundle for placement preparations.

Do upvote our blog to help other ninjas grow. 

Happy Coding!

Live masterclass