How to create a Debounce Function in Javascript?

About

A debounce is a function that:

For instance, in the context of:

debounce is said to come from the switch Contact bounce problem.

Usage

It's mostly used with event that triggers really often such as:

For example, in a search box that uses the change event, you don't want to search for every keystroke (ie to not search for every character of the search term)

Debounce function explained

This section will explain and comment on a debounce function to show how it works.

A debounce is a function that:

In Javascript, a call to the debounce function:

  • will schedule the target function to execute with the setTimeOut
  • delete the previous one if the debounce function was called again during the interval
  • let run the last schedule if the debounce function was not executed again during the interval

Function Signature

The signature of the debounce function has tree arguments:

  • funcToDebounce: the callback function to debounce
  • interval: the debounce interval in milliseconds where the debounce function should not be called to trigger the callback function execution.
  • leadingExecution: if true, execute the function:
    • before the interval (leading execution or immediate execution)
    • vs after (trailing execution)
function debounce(funcToDebounce, interval, leadingExecution) {

The timer Id

To execute after a certain amount of elpased time, the debounce function uses the setTimeOut function.

To keep track of the scheduled execution of the target function, we store the scheduler identifier (the returned value of the setTimeOut) in a timerId variable.

let timerId;

Every time that the debounce function is executed, this variable is not reset because we returns a function (it's called the closure functionality of javascript).

Returned function

Calling debounce returns a new anonymous function. Thanks to Javascript, this function is a closure and keeps track of its environment variables. The timerId will then persist and be available to this function.

return function() {

Scheduling condition

This condition checks if the function was already schedule.

It checks if timerId is a number (ie not null or undefined) and if this is the case it means that there is already a schedule running.

let wasFunctionScheduled = (typeof timerId === 'number');

Delete/Clear the previous schedule

The line below is the grand trick of the debounce function where:

  • we delete the previous scheduled execution
  • if the debounce function is called during the interval.

clearTimeout will delete the previous schedule function if timerId is valid/set or do nothing otherwise

clearTimeout(timerId);

The function to schedule

funcToSchedule is a wrapper function that:

Steps:

  • We first capture the execution parameters of the debounced function that we will pass to the execution function (apply)
let funcToDebounceThis= this, funcToDebounceArgs = arguments;
  • The funcToSchedule
let funcToSchedule = function() {

      // Reset
      clearTimeout(timerId);
      timerId = null;

      // trailing execution happens at the end of the interval
      if (!leadingExecution) {
        // Call the original function with apply
        funcToDebounce.apply(funcToDebounceThis, funcToDebounceArgs);
      }
      
}

Schedule the function to run at interval

Schedule each time an execution of the function over the interval.

timerId = setTimeout(funcToSchedule, interval);
  • If the debounce function is called again during this interval, it will be deleted with the previous clearTimeout
  • Otherwise, it will run

Leading Execution

If:

  • the callback function was not schedule before function entrance
  • the leading execution mode is on

Execute the function..

if (!wasFunctionScheduled && leadingExecution) funcToDebounce.apply(funcToDebounceThis, funcToDebounceArgs);

End of the returned function

}

End of debounce function

}

Demo: Mouse location

  • Printing the mouse location after a mousemove
function onMouseMove(e){
  console.log(new Date().toLocaleString()+": Position: x: "+e.x+ ", y:"+ e.y);
}
  • Debounce the onMouseMove function to not print for every mouve
let debouncedMouseMove = debounce(onMouseMove, 500);
  • Call the debounced function on every mouse move
window.addEventListener('mousemove', debouncedMouseMove);
  • Output: Move the mouse above the console below quickly without stopping, then stop, the last schedule event will then fire. ie when you:
    • move your mouse during the interval defined (500ms), all previous scheduling are deleted
    • stop moving the mouse for the interval defined (500ms), the last event will fire

Library

A debounce function is also generally available in utility library such as:

Debounce vs Throttle vs Deferred

  • A debounced function is called only once in a given period, delay milliseconds after its last invocation (the timer is reset on every call).
    • Debounce is great for keypress events; when the user starts typing and then pauses you submit all the key presses as a single event, thus cutting down on the handling invocations.
  • A throttled function is limited to be called no more than once every delay milliseconds.
    • Throttle is great for realtime endpoints that you only want to allow the user to invoke once per a set period of time.
  • A Deferred function defers updating the UI, and keeps showing the previous results until the new results are ready.
    • Unlike debouncing or throttling, it doesn’t require choosing any fixed delay.
    • If the work you’re optimizing doesn’t happen during rendering, use debounced or throttle.
    • In React 1):
      • as soon as the original re-render finishes,
      • React starts working on the background re-render with the new deferred value.
      • Any updates caused by events (like typing) will interrupt the background re-render and get prioritized over it.

Documentation / Reference





Discover More
Prosemirror Dom
How Rich Text editor in HTML are made (Principles and Demo)

How do you create a Rich Text editor in HTML, what are the well-known text editor and what are the principals. This article includes also a basic example where you can extend from to build your own
Devtool Chrome Event Listener
MouseMove Event

mousemove is an event that occurs when the pointing device is moved while it is over an element. The onmousemove attribute may be used with most elements. It permits to track the mouse location. ...
Card Puncher Data Processing
What is a Search box (Search bar)?

A searchbox or search bar is a combobox where the user enters a search term that should be searched in a collection of documents. The search may be: local in a list of rows (the document being a row)...
Devtool Chrome Performance Frames
requestAnimationFrame Web Api

requestAnimationFrame is a window function that permits to run code when a frame is going to be painted. Avoiding layout shift. For instance, when you create a fixed top bar, you need to set two...



Share this page:
Follow us:
Task Runner