Tuesday, October 28th, 2008
Delaying JavaScript Execution
<>p>Matt has a nice post on delaying JavaScript execution in a way that waits for certain events to finish:If you're looking to execute javascript code whenever someone finishes (or stops temporary) scrolling, moving the mouse, or resizing the page, you may find the following segment of code useful.
He shares the following boilerplate code:
-
-
var onFooEndFunc = function() {
-
var delay = 50; /* milliseconds - vary as desired */
-
var executionTimer;
-
-
return function() {
-
if (executionTimer) {
-
clearTimeout(executionTimer);
-
}
-
-
executionTimer = setTimeout(function() {
-
// YOUR CODE HERE
-
}, delay);
-
};
-
}();
-
This can be useful in a variety of ways, but it got me thinking about having the ability to download code lazily. For example, a friend shared information on an app that would wait for a click and then download code to run that functionality. This was bad, as it made it seem very slow indeed. Instead, the code could be split up into core (what has to be loaded as soon as possible) and then load other code when idly using this technique.








this code is very usefull in lot of ways. thanks for this.
Or as a method of the function object: http://www.jslab.dk/library/Function.defer
Shameless plug: I made something similar in Jquery plugin form a while ago except it lets you pass in a function making all of it easier :) Plus it’s JQuery so it automatically kicks ass.
http://ihatecode.blogspot.com/2008/04/jquery-time-delay-event-binding-plugin.html
Wow. Using setTimeout to delay code. That’s what it’s for. How is this newsworthy all of a sudden?
I’ve also seen this referred to as “function throttling” or “event handler throttling” – names aside, it’s a good (and in JS-land, sometimes important) pattern to have handy for event handlers in particular.
As for event handling, as one example, IE fires tons of resize()-related window events during a window drag-resize vs. Firefox which fires only one when the mouse stops moving (or on release of the mouse, I forget).. So reducing expensive calls can be useful. Nick Zakas and others (Heilmann I think) have similar approaches themselves.
@MichaelThompson -
The blog post is actually titled “Delaying Javascript Event Execution” not simply delaying any sort of javascript code execution. As Schill pointed out, it’s mainly used as a throttle for IE’s resize, scroll, etc events that fire often.
@Schill -
Thanks for pointing out Nick Zakas’ post, had not seen it before. It’s certainly a pattern developer’s should have in their solutions arsenal.
It’s called Submission Throttling in Ajax Design Patterns ( http://ajaxpatterns.org/Submission_Throttling ). It’s a special case of this general pattern…in this special case it’s intended for throttling calls to the server. In any event, the essence of the idiom/pattern is:
(1) Delay code execution after an event
(2) If a new event occurs while waiting, clear the timer and start waiting all over again
It is (2) that makes this more than just setTimeout.
There’s a demo of this in action here:
http://ajaxify.com/tutorial/ajaxagram/ajaxified/richer/performant/
You’ll notice if you keep hitting keys, it will never actually do anything. It’s only when you give it a break that it fires off the request. Interestingly, the app becomes more user-friendly AND more performant/scaleable, and in only 3 lines of code refactoring. (Transitioning it from an onkeypress handler to a timer mechanism.)
It’s used as an Ajax tutorial in the book and there’s some explanation here, under “Streamlining Performance”:
http://ajaxify.com/tutorial/
I often use this technique to do redrawing when neccessary but only after all current code has been executed. Methods in a complex object system signal that they need a redraw but only the last redraw will actually do anything. In this case it makes sense to set the delay to 0.
In general it makes sense to really grok JS’s execution model when doing serious AJAX development. We recents used this technique to implement a unit testing framework that waits for tests that execute asynchronously if neccessary.
Re delayed code loading, I have in past teamed delays with dojotookit’s “dojo.require”
The page loads and I load up the core code for the main menus etc. Once drawn I pause for a moment and then use dojo.require to bring in code that will be used elsewhere. dojo.require can be placed in a function and can load code at any time so you need only have something such as:
window.setTimeout(function(){
dojo.require(“something.blah”);
}, 3000);
The pause can make the UI feel stable and complete before quietly commencing background code loading.
I just finished a blog post on this, but just stumbled on this now.
Strictly speaking, this is “debouncing”, not “throttling”. Throttling is a technique that changes the rate of the event signaling. Debouncing ensures that only one event signal in a series of events goes through.
For a much more reusable version of a debounce method, go to (shameless plug):
http://unscriptable.com/index.php/2009/03/20/debouncing-javascript-methods/