Debounce Explained: Boosting Web Performance by Controlling Event Frequency

Sunil KhadkaSunil Khadka
3 min read

Introduction

Debounce is a technique used to rate the limit at which a function is called, particularly in response to user interactions like text input, mouse events, scroll etc. It helps improve performance by limiting excessive function calls.

Debouncing ensures that a function is only executed after a specified delay since the last time it was invoked. This means the function will wait for some additional time after the user has finished a series of rapid actions before execution. If the function is called within the specified delay, the counter resets.

A good example of debounce implementation is the auto save feature in the hashnode text editor itself or the Microsoft word. The editor will wait for a brief second (e.g 300 milliseconds) after the last keystroke before triggering the save operation. If you continue typing within that time period, the counter resets and the save function doesn’t execute until you stop typing.

How to implement debounce?

The basic idea involves the following steps:

  1. Create a debounce function. It should accept a callback and a delay as a parameter.

  2. Create a timer variable that stores reference to a setTimeout() and initialize it to null.

  3. Inside the debounce function, return a new function that handles the execution of callback after certain delay.

  4. Check if the timer holds reference to a setTimeout() inside the returned function. If it does, reset the timer by calling clearTimeout() on that timer variable. This ensures that any subsequent setTimeout() doesn’t execute while an event is being triggered.

  5. Set timer to a new setTimeout that will execute the callback function after the specified delay time. Pass any arguments from the new function call to callback if needed.

Example:

index.html

<input type="text" placeholder="type here..." id="input"/>
<p>Output: <span id="output"></span></p>

debounce.js

const input = document.getElementById("input");
const output = document.getElementById("output");

function debounce(cb, delay = 1000) {
    let timer = null;
    return (text) => {
        clearTimeout(timer);
        timer = setTimeout(() => cb(text), delay)    
    }
}

const debounceEventHandler = debounce((text) => {
    output.innerText = text
})

input.addEventListener("input", (e) => {
    debounceEventHandler(e.target.value)
})

Implementation Example

I created a simple name searching example to simulate how a debounced function makes a significant difference in the number of APIs requested vs when a function isn’t debounced. You can check and uncheck the debounce checkbox to switch between debounce mode.

Real World Use Cases

  1. Auto complete: Debounce is commonly used in auto-complete features like search bars or text input, to delay the execution of search function until the user has stopped typing for a certain amount of time.

  2. Auto Save: Debounce can be used to implement auto save features in text editors such as hashnode text editor or Microsoft Word to automatically save changes once the user stops typing.

  3. Form Validations: Debouncing can be used to delay form validation until the user has stopped interacting with the form for a certain amount of time. This prevents excessive validation attempts and improves user experience.

  4. Button Clicks: Debouncing can be used to delay the execution of button click events. This ensures that event isn’t triggered frequently when user rapidly clicks a button.

  5. Window resizing: Debouncing can be applied to window resize events to prevent excessive function calls and improve performance. This is particularly useful in applications with complex layout calculations.

  6. Mouse scroll: Debouncing can be used to only load the content once the user stops scrolling. This ensures a function isn’t triggered for each pixels scrolled.

Debounce vs Throttle

  • Debounce delays the execution of a function until after the specified delay has passed since the last time the function was called. In other words, debounce “waits” for inactivity before executing.

  • Throttle, on the other hand, doesn’t wait for user interactions to stop before executing functions. Throttled functions run at regular intervals (like every 500ms), no matter how many times the triggering event occurs within that time frame.

0
Subscribe to my newsletter

Read articles from Sunil Khadka directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Sunil Khadka
Sunil Khadka

I am a Full-Stack Engineer with more than 2 years of experience building complex web applications. I use React.js and Golang for frontend and backend development. There's nothing like one size fits all and I try to learn as many new technologies as possible.