Javascript optimization micropatterns: debouncing and throttling decorators
Function decorators allow you to add additional function behavior without changing it. The signature of the original and decorated function is exactly the same.
If literally translated - "elimination of bounce." Such a decorator allows you to turn several function calls within a certain time into one call, and the delay begins to re-count with each new call attempt. Two options are possible:
For example, you have suggest. Sending server requests to each is
Or you have one handler for several events, and it is necessary that if both events occur for some time, the handler works only on the last event that occurred:
This decorator allows you to "brake" the function - the function will be executed no more than once in a specified period, even if it will be called many times during this period. Those. all intermediate calls will be ignored.
For example, on
My implementations of these decorators as a jQuery plugin can be downloaded from code.google .
Ps. It is inspired by Nicholas Zakas’s book, Professional JavaScript for Web Developers, 2nd Edition , although it confuses it
Debouncing
If literally translated - "elimination of bounce." Such a decorator allows you to turn several function calls within a certain time into one call, and the delay begins to re-count with each new call attempt. Two options are possible:
- A real call occurs only if a time greater than or equal to the delay has elapsed since the last attempt.
- A real call occurs immediately, and all other call attempts are ignored until a time elapses greater than or equal to the delay counted from the time of the last attempt.
Using
debouncedFn = $.debounce(fn, timeout, [invokeAsap], [context]);
- fn - original function
- timeout - delay
- invokeAsap -
true
/false
, by defaultfalse
. A parameter indicating which of the above optionsdebouncing
should be used (the first is used by default) - context - context of the original function
Usage example
For example, you have suggest. Sending server requests to each is
keyup
wasteful and unnecessary. You can decorate the handler so that it only works after the user has stopped pressing keys, for example, for 300 milliseconds:function onKeyUp() { ... };
$('input[name=suggest]').keyup($.debounce(onKeyUp, 300));
* This source code was highlighted with Source Code Highlighter.
Or you have one handler for several events, and it is necessary that if both events occur for some time, the handler works only on the last event that occurred:
$('input').bind('keyup blur', $.debounce(process, 300));
* This source code was highlighted with Source Code Highlighter.
Throttling
This decorator allows you to "brake" the function - the function will be executed no more than once in a specified period, even if it will be called many times during this period. Those. all intermediate calls will be ignored.
Using
throttledFn = $.throttle(fn, period, [context]);
- fn - original function
- period - period
- context - context of the original function
Usage example
For example, on
resize
windows (or, let's say, on mousemove
), some heavy handler is triggered. You can "brake" it:$(window).resize($.throttle(doComplexСomputation, 300));
As a result, the function will be executed no more than once every 300 milliseconds. My implementations of these decorators as a jQuery plugin can be downloaded from code.google .
Ps. It is inspired by Nicholas Zakas’s book, Professional JavaScript for Web Developers, 2nd Edition , although it confuses it
debounce
and throttle
calls the first the second. Ajaxian also raised this topic .