DEV Community

Cover image for What is Throttle, What is the Throttle use, and how to create Throttle?
Amir-Lotfi
Amir-Lotfi

Posted on

What is Throttle, What is the Throttle use, and how to create Throttle?

These days applications are more complicated than ever. Meanwhile, users expect no lag or slowdown in user experience, which makes the developer's job more difficult. Fortunately, there are many hacks like throttle; that can help with performance without sacrificing functionality. In this tutorial, we will learn about the throttle and its implementation.

What is Throttle?

Throttle is a function that takes a callback as an argument and executes the callback only once during a given timeout. Throttle will call the callback passed to it every time the timeout ends as long as the trigger for the callback is still happening.

What is the Throttle use?

The throttle is used for performance optimization. When you have recurring events like scrolling, resizing, or drag and drop, you can use the throttle to restrict the code execution, thus reducing resource use.

How to create Throttle?

To create throttle, fork this template which provides a slider that updates the dom on event input. We learn how to create and add throttle to the slider in the following steps.

Step one, define throttle function.

Create a function; named throttle that takes the callback function and timeout as arguments and returns a closure that executes the callback with arguments passed to it.

function throttle(callback, timeout = 1000) {
    // pass arguments to callback
    return (...args) => {
        callback(...args)
    }
}
Enter fullscreen mode Exit fullscreen mode

Then wrap the function slider in throttle like below. You can pass the timeout as the second argument.

const slide = throttle(() => {
    placeholder.innerText = slider.value;
})
Enter fullscreen mode Exit fullscreen mode

Now the function slider executes through the throttle.

Step two, add the timeout stage.

Define a variable named wait that indicates the timeout stage. The wait variable default value must be false to execute the callback at the first trigger. After the first callback execution, we set the variable wait to true and add; a condition before the callback to ignore future calls if the throttle is in the timeout stage.

function throttle(callback, timeout = 1000) {
  let wait = false
  return (...args) => {
    if (wait) return
    callback(...args)
    wait = true
  }
}
Enter fullscreen mode Exit fullscreen mode

Now, the callback executes for the first time, but other triggers get ignored, and we can test that by sliding the slider thumb.
To execute other callback triggers, we have to add a setTimeout with a delay equal to the timeout argument to reset the wait variable and end the timeout stage.

function throttle(callback, timeout = 1000) {
  let wait = false
  return (...args) => {
    if (wait) return
    callback(...args)
    wait = true

    setTimeout(() => {
      wait = false
    }, timeout)
  }
}
Enter fullscreen mode Exit fullscreen mode

Step three, queue the calls.

Now the throttle works, but there is a problem it ignores the last trigger. We can test that by sliding the slider thumb again before the timeout ends. To resolve that issue, we need to queue the last trigger during the timeout stage and execute the last trigger at the end of the timeout.
To do that, we need a variable name queue to store the last trigger arguments if we are in the timeout stage.

function throttle(callback, timeout = 1000) {
  let wait = false
  let queue = null
  return (...args) => {
    if (wait) {
        return queue = args
    }
    callback(...args)
    wait = true

    setTimeout(() => {
      wait = false
    }, timeout)
  }
}
Enter fullscreen mode Exit fullscreen mode

Then to execute queued trigger, we need a function that runs the callback, and we have to run that function after the timeout ends.
Therefore, define a function named queuedTasks. Inside that function, call the callback with queued arguments. After the callback execution, empty the queue by setting its value to null. Then, add a condition at the beginning of queuedTasks to check if the queue is empty, so we end the waiting stage. In the end, define a setTimeout that calls queuedTasks again to execute triggers that happened in the timeout stage.

function throttle(callback, timeout = 1000) {
  let wait = false
  let queue = null

  const queuedTasks = () => {
    if (queue == null) {
      return wait = false
    }

    callback(...queue)
    queue = null
    setTimeout(queuedTasks, timeout)
  }

  return (...args) => {
    if (wait) {
      return queue = args
    }

    callback(...args)
    wait = true

    setTimeout(queuedTasks, timeout)
  }
}
Enter fullscreen mode Exit fullscreen mode

Now the slider should work just fine and excessive calls get ignored which improves the application performance. You can see the final code here.

To conclude

The throttle can optimize your application performance and gives it a premium look that can directly translate to an increase in user engagement and monetization of your application.

Challenge your skills

A little while ago, I wrote a tutorial on how to create a scroll to top button. In that tutorial, I wrote a small piece of javascript code that toggles a class to the scroll to top button according to scroll position. That javascript code performance can be improved with the throttle. As a challenge, fork that code and try adding throttle to it and share your code with others in the comment section below.

Latest comments (0)