A debounce function takes a function & returns an optimized version of it. The optimized version groups a sudden burst of function calls into 1.
How It Works
debouncedFunc is invoked, a timer will start.
When the timer completes,
func is invoked.
debouncedFunc is invoked again before the timer completes, the timer will restart.
There are 2 types of debounce implementations:
- ▪ Trailing Edge: The above implementation.
funcis invoked AFTER the timer has completed.
- ▪ Leading Edge:
funcis invoked BEFORE the timer starts. When the timer completes,
funcwill not be invoked. Implementation below.
Input validation. Imagine a form with an email input. Each time the user enters a character, a validation function is invoked. If the input value is not in a valid email format, it renders a error message.
This UX isn't great. An error message will be shown as soon as the 1st character is entered into the input. An improvement would be to instead invoke the validation function only after the user has finished entering all characters of their email address. This can be done by debouncing the validation function.
A throttle function takes a function & returns an optimized version of it. The optimized version prevents a function being called more than once every X milliseconds.
How It Works
throttledFunc is invoked,
func will be invoked & a timer will be started.
Until the timer completes, any calls to
throttledFunc will not invoke
Window scroll callback. Imagine you set a callback for the window scroll event. It could be invoked up to 30 times per second. Depending on what the callback was doing, a lot of these could redundant. While the browser is processing all them, it could block execution, making the browser unresponsive. Throttling the callback would reduce the number of invokes.
window.requestAnimationFrame is a method provided by the browser that will throttle a function.
It requests the browser invokes a function before the next repaint.
requestAnimationFrame can be thought of as a throttle with
waitMS = 16 (60fps).
However, internally will decide the best timing on how to schedule the rendering.
It has a much higher fidelity than a common throttle being a browser native API that aims for better accuracy.
When a property like opacity is changed, the user won't see that change until the browser does a repaint.
Imagine you have an element with an opacity of 1.
You create a function that change that element's opacity.
You invoke the function twice, once to change it to
0.9, then again the change it to
If both of those calls occur before the browser does a repaint, then the 1st will have no effect.
The user will only see the element change from
These unrequired invokes can be avoided using
How It Works
You pass a function to
It won't be invoke until the browser is ready to make the next repaint.
When a function is painting or animating properties & you want to guarantee smooth changes.
For example, changing the opacity of an element based on the scroll position.
Below, we use
requestAnimationFrame when a new value for opacity needs to be set.
If that value changes before a repaint, we cancel the request & set a new 1 with the latest value.
viewportHeight is being calculated unnecessarily every update.
It couldn't be moved outside of the function.
Possibly related to iframe loading delay.
In the above examples,
callback.call(..) is used instead of
This is to ensure the correct
this value is bound.