If you’ve written any kind of validation on user input, like onkeypress
then you’ll know that sometimes you want to throttle the amount of times your function runs. A good example of this is Ajax based username validation - you don’t want to hit the server on every key press, because most users will be able to write their name in around 1/10th of a second, so you should throttle the ajax request until the input is dormant for 100ms.
[](https://training.leftlogic.com/buy/terminal/cli2?coupon=BLOG\&utm_source=blog\&utm_medium=banner\&utm_campaign=remysharp-discount)
[READER DISCOUNTSave $50 on terminal.training](https://training.leftlogic.com/buy/terminal/cli2?coupon=BLOG\&utm_source=blog\&utm_medium=banner\&utm_campaign=remysharp-discount)
[I’ve published 38 videos for new developers, designers, UX, UI, product owners and anyone who needs to conquer the command line today.](https://training.leftlogic.com/buy/terminal/cli2?coupon=BLOG\&utm_source=blog\&utm_medium=banner\&utm_campaign=remysharp-discount)
[$49 - only from this link](https://training.leftlogic.com/buy/terminal/cli2?coupon=BLOG\&utm_source=blog\&utm_medium=banner\&utm_campaign=remysharp-discount)
2½ years later, I decide that [Ben was right](#comment-216435) - and nowadays I refer to this as a debounce rather than a throttle. I’ve updated this post so that the function name reflects what it does on the tin, but also add my own throttle function that fires the callback based on a specific frequency. The throttle function will also always fire the first and last message.
So with a bit of magic JavaScript making use of the ever useful [closure](http://en.wikipedia.org/wiki/Closure_\(computer_science\)) JavaScript offers, we can create a simple method to handle this for us:
function debounce(fn, delay) {
var timer = null;
return function () {
var context = this, args = arguments;
clearTimeout(timer);
timer = setTimeout(function () {
fn.apply(context, args);
}, delay);
};
}
So if you were doing something with jQuery, like a key press validation, you would do this instead:
$('input.username').keypress(debounce(function (event) {
// do the Ajax request
}, 250));
The keyword this
is the input as you would expect, and all the correct arguments are passed to the event handle, i.e. it works the exact same way as you’d expect, except it only fires once the keypress
event is idle for 250ms (in this particular case).
Below is an actual throttle function, that fires a message every 250ms by default (rather than at the end of a burst of events):
function throttle(fn, threshhold, scope) {
threshhold || (threshhold = 250);
var last,
deferTimer;
return function () {
var context = scope || this;
var now = +new Date,
args = arguments;
if (last && now < last + threshhold) {
// hold on to it
clearTimeout(deferTimer);
deferTimer = setTimeout(function () {
last = now;
fn.apply(context, args);
}, threshhold);
} else {
last = now;
fn.apply(context, args);
}
};
}
So when you use this, moving the mouse around the [example below](https://jsbin.com/enowox/1/edit), will echo out the tick on the first time you move, but then every 1 second until you stop moving the mouse:
$('body').on('mousemove', throttle(function (event) {
console.log('tick');
}, 1000));
There’s also a [simple rate throttled function](/2010/07/21/throttling-function-calls/#comment-497362) in the comments below, that fires on every nth message - though I’d be inclined to tweak it to ensure the first message is delivered
Published 21-Jul 2010 under #code & #development & #javascript & #jquery. [Edit this post](https://github.com/remy/remysharp.com/blob/main/public/blog/throttling-function-calls.md)
Comments
Lock Thread
Login
Add Comment[M ↓ Markdown]()
[Upvotes]()[Newest]()[Oldest]()

Reza S
0 points
6 years ago
threshhold →threshold

Gregory Thomson
0 points
6 years ago
This is better:
throttle = function(func, obj, evt) {\ var timeouttype= 0,\ newThrottleFunc;\ return ( // The following is required so that Mute works properly\ cachedThrottleListeners\[ cachedThrottleFuncs.indexOf(func) ] || (\ cachedThrottleObjects.push( obj ),\ cachedThrottleEvents.push( evt ),\ cachedThrottleFuncs.push(func),\ cachedThrottleListeners.push(newThrottleFunc = function(Evt) {\ var that = this;\ switch (timeouttype){\ case 0: // Execute immediatly\ timeouttype = 1;\ requestAnimationFrame(func.b(this, Evt));\ break;\ case 1: // Delayed execute\ timeouttype = 2;\ setTimeout(function(){\ timeouttype=0;\ requestAnimationFrame(func.b(this, Evt));\ }, 45 /threshold/ - ([Date.now](http://Date.now)() % 45 /threshold/) );\ }\ }),\ newThrottleFunc\ )\ );\ };
Instead of dealying the event, which can sometimes cause undesireable effects, and can cause the event not to fire when you want it to, this version immediatly executes the function if it has been more than the set interval since the previous call, else instead of dropping the function call it just delays it till it would be appropriate. So yes, this is much better because causes zero undesirable effects.

-
Korman
0 points
6 years ago
Thanks for sharing this! Even coming up with a name ("debouncing") help me organise my head around it and find a good way to do something similar in my code. I spent quite a few hour hammering into shape, but the main idea is the same.

Ajinkya
0 points
7 years ago
use lodash\
_.debounce(searchFilter, 300)

Russ
0 points
7 years ago
Commenting on a 6yo post… Yikes.
Rather than using just 'threshold' as the delay in the setTimeout, use 'threshold + last - now'. This prevents the last event from firing at an oddly spaced time by calculating how much time is left until the next event was going to be allowed to fire and using that. This stops phantom key presses that occur because a final repeated event was fired just at the end of the current threshold, thus causing the last event to happen after a weird delay.
Here’s the minor tweak in a copy/pastable chunk:
`\`\ function throttle(fn, threshhold, scope) {\ threshhold || (threshhold = 250);\ var last,\ deferTimer;\ return function () {\ var context = scope || this;
var now = +new Date,
args = arguments;
if (last && now < last + threshhold) {
// hold on to it
clearTimeout(deferTimer);
deferTimer = setTimeout(function () {
last = now;
fn.apply(context, args);
}, threshhold + last - now);
} else {
last = now;
fn.apply(context, args);
}
};\ }\ `\`
-Russ

Jason
0 points
7 years ago
Thanks, very helpfull

Paul Browne
0 points
8 years ago
A debounced resize handler that fires ONLY when the width changes

Max Yari
0 points
9 years ago
This throttle was amazing. Analysing was a great learning experience. I ecen didn’t know, that you can call function on whatevr context you like with apply, and that you can cancel timeout without any boolean checks, awesome. thanks)

Ryan Taylor
0 points
9 years ago
Edit: Corrected post. In many cases you want to pass the arguments from the last call into the function too, that’s why setTimeout is used. Thanks rem. This makes it almost identical the above function, so, to prove my worth, I made it shorter. :P
function throttle(func, ms){ var timeout, last = 0 return function(){ var a = arguments, t = this, now = +(new Date), exe = function(){ last = now; func.apply(t,a) } clearTimeout(timeout) ;(now >= last + ms) ? exe() : timeout = setTimeout(exe, ms) } }
Old Comment: You don’t need the setTimeout for throttling! Think about it…
function throttle(func, ms){ var last = 0; return function(){ var a = arguments, t = this, now = +(new Date); //b/c last = 0 will still run the first time called if(now >= last + ms){ last = now; func.apply(t, a); } } }

rem
0 points
9 years ago
You’d also always lose the last call if it was inside the threshold, and the last one is the one you absolutely want.

Ryan Taylor
0 points
9 years ago
you’re totally right, you want to pass the arguments from the very last call into the throttled function.

rem
0 points
9 years ago
I can’t easily test the rest of this code, but now >= last + ms
where last
is undefined
, results in now >= NaN
which is false
- so it shouldn’t work first time.

Bhavya wadhwa
0 points
9 years ago
can i modify it like this, so as to not execute the function if invoked between the threshold period\ function throttle(fn, threshhold, scope) {\ threshhold || (threshhold = 250);\ var last,\ deferTimer;
return function () {\ var context = scope || this;\ var now = +new Date,\ args = arguments;\ if (last && now < last + threshhold) {\ last = now;\ return;\ } else {\ last = now;\ fn.apply(context, args);\ }\ };
}
?
Anonymous
0 points
10 years ago
Hi, I think there’s a bug in your throttle function, you still need to clearTimeout(deferTimer);
in you else
clause, before you fn.apply(context, args);
Otherwise it is possible for deferred and not deferred function invocations to be run with less that threshold
interval.
?
Anonymous
0 points
10 years ago
Hi,
I am working on a auto search function. Here, i want to execute the function after 2 second of last key press.(exactly same requirement as in [http://stackoverflow.com/qu…;](http://stackoverflow.com/questions/4364729/jquery-run-code-2-seconds-after-last-keypress) ). I m using this code but it is not working fine.
`\`\ function throttle(f, delay)\ {\ var timer = null;\ return function()\ {\ var context = this, args = arguments;\ clearTimeout(timer);\ timer = window\.setTimeout(function()\ {\ f.apply(context, args);\ },\ delay || 500);\ };\ }
function searchfunc()
{
alert(document.getElementById('Searchtxt').value);
}
`\`
Will you please help me out.
Thanks in advance,\ Shruti
?
Anonymous
0 points
10 years ago
How does this throttle behave for slow functions? Will they get stacked of does the threshold indicate the idle time?
?
Anonymous
0 points
11 years ago
you should checkout underscore.js - it has a whole load of utility functions like this.
?
Anonymous
0 points
11 years ago
Thanks for this Remy. I followed cowboy’s link to unscriptable’s article on throttling/debouncing. If your example above is really debouncing then I guess an actual throttle function would look like this right?:
var throttle = function(func, rate){ var counter = 0; return function(){ var context = this; var args = arguments; counter++; if(counter === rate){ func.apply(context, args); counter = 0; } } }
?
Anonymous
0 points
11 years ago
humm, its really helpful for me cause, before i was doing that silly trick to call server on every keyperss. Thanks a lot to describe and share.
?
Anonymous
0 points
11 years ago
Very elegant. Got it working beautifully on an autocomplete I am making (don’t want to use a whole autocomplete plug in for a few reasons). A problem I ran in to is that I only want it to fire if certain keys are pressed in to the input box (namely, a-zA-Z0-9). For the rest of the keys (arrows, tab, shift, etc), I want to take different actions but I don’t want a delay to occur when those select buttons are pressed. I have a switch setup on the keyCode to do certain things for certain keys, then the default behavior is executing the AJAX fetch a list of suggestions. Any idea how I could use the throttle function in the default behavior of that switch? simply: throttle(function() { /\* fetch code \*/ }); does not work, but also does not produce any errors. I’m kind of a JS/jQuery noob, so any assistance would be appreciated. Thanks.
?
Anonymous
0 points
12 years ago
Just out of interest, which do you prefer? 100ms or 250ms delay :D

englishextra
0 points
6 years ago
100
?
Anonymous
0 points
13 years ago
Yes it’s pretty awesome for autocomplete (sometimes for mousemove, but the "real" throttle is more likely to be used in that case).
For the ones who want to use it without jQuery:
One thing to note is that for IE you need to save (shallow copy) the event object, otherwise the delayed function can’t use it, because it’s only available when the event is active.
?
Anonymous
0 points
13 years ago
Remy, Just read your book on HTML5- fantastic! I have a question for you completely unrelated to this post. I just thought I might ask you since your knowledge of jQuery is far superior to mine! I simply need to get this jQuery plugin to 'auto-rotate' - its called [SweetPages](http://tutorialzine.com/2010/05/sweet-pages-a-jquery-pagination-solution/) - think you could help me out?? Thanks Remy!! Hope you can help.
?
Anonymous
0 points
13 years ago
Good name = "chocke", or even better jQuery.choke(dn, delay)\ :)
?
Anonymous
0 points
13 years ago
Hello
thank you for this.\ Never thougt it could be called 'debouncing', but I found this - it’s awesome little code snippet!:)
cute
?
Anonymous
0 points
13 years ago
@cowboy - I know this technique is called "debouncing" - but in english, fewer developers will know what you mean and throttling, although technically inaccurate, actually is pretty obvious what you’re doing - simplicity of specificity :)
Equally this article: 3 paragraphs, and 8 lines of code - a lazy developer is a happy developer ;-)
?
Anonymous
0 points
13 years ago
The first time I read about this technique (referred to most often as "debouncing") was in unscriptable’s [Debouncing Javascript Methods](http://unscriptable.com/index.php/2009/03/20/debouncing-javascript-methods/) article.
Check out my [jQuery throttle / debounce plugin](http://benalman.com/projects/jquery-throttle-debounce-plugin/) (that David linked) for an in-depth explanation of the difference between throttling and debouncing (complete with graphs!), as well as a few "alternate" modes for each.
Consider that a function can be debounced at either the beginning OR the end of a series of repeated calls. For example, due to the way people type, when "throttling" AJAX requests triggered by keyboard input, you typically want to wait until the user has paused for a moment before submitting the query. On the other hand, when dealing with game input, you may actually want the first—but ONLY the first—keypress, within a given time period, to trigger an action.
And don’t forget about basic throttling, which is simply rate-limiting a function so that it executes no more than once every N milliseconds. Throttling is especially useful in normalizing the scroll and resize events in IE and Safari, which are fired far more frequently than in Firefox (which can cause problems if you’re doing anything computationally expensive).
?
Anonymous
0 points
13 years ago
@pop - because the arguments
are required inside of the setTimeout firing. If I use arguments
in the setTimeout, they’d be blank since I hadn’t passed any in.
?
Anonymous
0 points
13 years ago
Why do you use "var args = arguments" instead of "arguments" ?\ Is it only for a better reading experience? For performance (so why?)?\ Thanks
?
Anonymous
0 points
13 years ago
Good things come in threes ;-)
?
Anonymous
0 points
13 years ago
Heh, I wrote about this yesterday: [http://fitzgeraldnick.com/w…;](http://fitzgeraldnick.com/weblog/32/)
So did Angus Croll: [http://javascriptweblog.wor…;](http://javascriptweblog.wordpress.com/2010/07/19/a-javascript-function-guard/)
Its a cool technique to say the least.
?
Anonymous
0 points
13 years ago
What an elegant and useful little function! I think the name "throttle" might be a tad misleading, but I’ll be damned if I can come up with a better name! :)
Ben Alman’s fantastic description of throttling vs. debouncing might be helpful here:
Either way, thanks for sharing!
[Commento](https://commento.io)