Problem: Jumpy execution during UI changes
The classic case is windows resizing. When we have a responsive webpage, we want to resize our site’s interface to match the actual viewport size. While most of the work is done via CSS, we still might need to run some JS to complete the action. Our first attempt to handling this would be so something like this (in jQuery):
// Do our things here
If you resize the window by dragging it, the event handler gets fired several times, causing the browser to redraw every time it’s called. And, if the event handler has some heavy operations in it, the page will get really sluggish. In some extreme cases, it can even crash the browser.
Debouncing events firing
Use cases for a debouncing function
Use it to discard a number of fast-pace events until the flow slows down. Examples:
- UI changes produced by continuous action, such as scrolling, window dragging or moving the mouse over a DIV.
- When typing fast in a textarea that will be processed: you don’t want to start to process the text until user stops typing.
- When saving data to the server via AJAX: You don’t want to spam your server with dozens of calls per second.
Example solution 1: use Underscore’s debounce function
This library has a “debounce” function to get rid of the resizing event being fired too often by wrapping the handler in Underscore’s debouncing function. _.debounce(function, wait, [immediate])
What is does (from the official documentation) is creating and returning a new “debounced” version of the passed handler. This will postpone its execution until after “wait” milliseconds have elapsed since the last time it was invoked. So, now we can rewrite our code as:
// Do your stuff here
A waiting time of 500 milliseconds works very well in most situations but you can play with times to get the result we want.
window.resizeEvt = setTimeout(function()
if($(window).width() != previous_width)
//Do your stuff here
This function does the same as the “debounce” function by setting a timeout each time the “resize” event is fired.
If the event was not fired for at least 250ms, it is assumed that window resize has completed and then we proceed to do whatever it was supposed to happen if the windows changed its size. It is pretty useful if you don’t intend to use Underscore or another external library.
As mentioned above, window resizing is the most common use case for debouncing, but you could also use it for key events that trigger an autocompleter, or any continuous or fast-pacing action.