What is Debouncing? Explain with examples

Friday, April 26, 2024

Web performance is a key aspect and often discussed interview topic. All companies want their websites to load faster, stay performant, and provide smooth user experience.

Debouncing is one of the techniques used to improve performance by limiting the frequency of a particular function being called, particularly in scenarios where the function is triggered frequently, such as input events like typing in an input field or scrolling. This ensures that the function is only called once after a specified period of inactivity.

Implementation

We can implement Debounce by creating a Higher Order function that will take the original function and a delay amount as input and returns a debounced version.

function debounce(fn, delay) {
  return function executedFunction() {
    // some processing
  }
}

The main behaviour of the debounce function is to defer the execution of the original function by the delay provided as the argument. We can do so by using the setTimeout method.

function debounce(fn, delay) {
  let timer;

  return function executedFunction() {
    timer = setTimeout(function() {
      fn();
    }, delay);
  }
}

The idea is to call the original fn function if there is no user action for delay milliseconds. On every user action, the executedFunction would be called every timing. As per our current implementation, we are going to set a new timer that would result in n API calls. However, this is not the desired behaviour, we need to clear the old timer and set a timer on every user action.

function debounce(fn, delay) {
  let timer;

  return function executedFunction() {
    // clearing the current timer
    clearTimeout(timer);

    // settings a new timer
    timer = setTimeout(function() {
      fn();
    }, delay);
  }
}

Now, we need to pass the arguments provided by the user to the original fn function.

function debounce(fn, delay) {
  let timer;

  return function executedFunction() {
    // arguments is an array-like object accessible inside a function
    // it contains all the input arguments provided to the user
    // we are converting it to an actual array using slice
    const args = Array.prototype.slice.call(arguments);
    // storing calling reference
    const context = this;

    // clearing the current timer
    clearTimeout(timer);

    // settings a new timer
    timer = setTimeout(function() {
      // invoking the fn with current context (this) and passing args
      // apply method changes the context and takes arguments as an array
      fn.apply(context, args);
    }, delay);
  }
}

This satisfies are all requirements. We are returning a debounced version of the original function that is invoked after every n milliseconds.

Examples

One example of debouncing is in handling search input on a website. Imagine a scenario where a user is typing in a search box to filter results. Without debouncing, a search API call would be triggered on every keystroke, leading to multiple unnecessary API calls. By implementing debouncing, we can delay the API call until the user stops typing for a specified amount of time, therefore reducing the number of API requests made and improving the overall performance of the search feature.

function search(query) {
  ...
  // make API call here
}

const debouncedSearch = debounce(search, 300);

// debouncedSearch method either inside useEffect or onChange

Practice

This concept is asked an interview questions of multiple companies like Flipkart, Visa, Amazon, and many more. You can try and see if you can pass all the test cases using the link below.

https://devtools.tech/questions/s/implement-debounce-function-or-flipkart-ui-javascript-interview-questions---qid---CVSyd8uTdvVt1l2YcAcq

Unsure about your interview prep? Practice Mock Interviews with us!

Book Your Slot Now