

Actually, the throttle function is defined using _.debounce with maxWait, as you see in the lodash source code. The new maxWait option (only in Lodash at the moment) is not covered in this article but it can be very useful. By default, only the trailing edge is enabled. The original immediate flag was replaced with leading and trailing options. Lodash has added more features to its _.debounce and _.throttle functions. Since then, both implementations have grown apart. There was a time that underscore adopted the debounce/throttle implementation from Lodash, after I discovered a bug in the _.debounce function in 2013. The 3 implementations are a bit different internally, but their interface is almost identical. It was later added to Lodash, a drop-in alternative to underscore. Soon after that, Ben Alman created a jQuery plugin (no longer maintained), and a year after, Jeremy Ashkenas added it to underscore.js. The first time I saw debounce implemented in JavaScript was in 2009 in this John Hann post (who also coined the term). In underscore.js, the option is called immediate instead of leading You can do this! Here’s an example with the leading flag on: Example of a “leading” debounce. Why not trigger the function execution immediately, so it behaves exactly as the original non-debounced handler? But not fire again until there is a pause in the rapid calls. You may find it irritating that the debouncing event waits before triggering the function execution, until the events stop happening so rapidly. But if the events are triggered with big gaps, the debouncing doesn’t happen.

You can see how sequential fast events are represented by a single debounced event.

Click or move the mouse on top of the button: The elevator is delaying its function (moving floors), but optimizing its resources. Now it happens again with another person. The elevator doesn’t begin its function to change floors, the doors open again. The doors begin to close, and suddenly another person tries to get on. The Debounce technique allow us to “group” multiple sequential calls in a single one. We’ll also look at the matching use cases. Let me introduce you to Debounce, Throttle, and requestAnimationFrame. These days there are slightly more sophisticated ways of handling events. With this simple technique, we can avoid ruining the user experience. That way the handler is not coupled to the event. The suggested solution by John (at that time, five years ago) was a loop running every 250ms, outside of the onScroll event. John Resig published a blog post about the problem where it was explained how bad of an idea it is to directly attach expensive functions to the scroll event. In 2011, an issue popped up on the Twitter website: when you were scrolling down your Twitter feed, it became slow and unresponsive. Is your scroll handler prepared for this rate of execution? But scrolling slowly (swapping) in a smartphone could trigger as much as 100 events per second during my tests. When scrolling using a trackpad, scroll wheel, or just by dragging a scrollbar can trigger easily 30 events per second. See the Pen Scroll events counter by Corbacho ( on CodePen. It can vary.įor example, let’s talk about scroll events. Remember, we don’t control how often those DOM events are going to be emitted. Why? Because we are giving ourselves a layer of control between the event and the execution of the function. Having a debounced or throttled version of our function is especially useful when we are attaching the function to a DOM event. We’ve broached this topic before, but this time, David is going to drive the concepts home through interactive demos that make things very clear.ĭebounce and throttle are two similar (but different!) techniques to control how many times we allow a function to be executed over time. The following is a guest post by David Corbacho, a front end engineer in London.
