Debounce and Throttle Functions in JavaScript

Improve performance by limiting function calls in JavaScript with Debouncing and Throttling.

You may encounter times when the performance of your JavaScript is affected by too many function calls. This can happen, for example, when you have event handlers on an input field and you type too fast, or an even handler on a window resize event, which causes the function to be called on every pixel resize. These repetitive function calls can be drastic to the performance of your application. The good news is this can be mitigated by using debouncing and throttling.

What is Debouncing and Throttling in JavaScript?

Debouncing and throttling are higher order functions used to increase the performance of your JavaScript function calls by limiting or slowing down the number of continous invocations. This may seem complicated, but the basic idea is: limit the number of times you call a function. Throttling and debouncing both do this but there are subtle differences between the two.

Throttling limits the number of times a function is called but calls the function continously while spacing out the invocation intervals.

Debouncing waits until a continous function call is stopped for an amount of time, then it invokes the function.

As illustrated, clicking on the download buttons many times will have different effects depending on if throttled, debounced or not limited at all.

Getting to the point, here what the throttle and debounce function codes look like.

Throttle Function

const throttle = (fn, milliseconds) => {
  let inThrottle
  return function () {
    const args = arguments
    const context = this
    if (!inThrottle) {
      fn.apply(context, args)
      inThrottle = true
      setTimeout(() => (inThrottle = false), milliseconds)
    }
  }
}
// Wrap the function you want to throttle along with the time in milliseconds you want to delay each call.
throttle(clickHandler, 1000)

Debounce Function

const debounce = (fn, milliseconds) => {
  let debounceTimer
  return function () {
    const context = this
    const args = arguments
    clearTimeout(debounceTimer)
    debounceTimer = setTimeout(() => fn.apply(context, args), milliseconds)
  }
}

// Wrap the function you want to debounce along with the time in milliseconds you want to wait before calling.
debounce(clickHandler, 1000)

As you can see, they are both "higher order functions" that wrap any function with a time limit. Using setTimeout they can decide when to invoke the function based on the time delay parameter.

Have some feedback on this post? .