Optimizing Javascript - Load and wait
Sunday 7 October 2007 / 15:22 [ IT] # 4
Load everything from the start = bad
I've been optimizing most of our AJAX apps lately, and found out (thanks to YSlow) that one of the many causes of the sluggish load time of these apps is the fact that every JS file that might be needed during user session is loaded right at the start of the app.Obviously, I didn't need YSlow to realize that it was a very bad thing. As an OO programmer, I have learned to instanciate an object only and only when I'm going to use it. So, in a webapp context, why loading every possible javascript file when I just need a bunch of them ? The thing I needed was dynamic JS loading.
On demand Javascript
The next question was : "technically, how do I tell the browser to load a JS file after the page has been loaded ?". I found the solution at Ajaxpatterns.org, in this article about on-demand JS. It shows that basically, loading a file after page load is no more than adding a new DOM node to the document tree.That said, loading a new JS into memory is one thing, but the article underlines another related problem without giving directly the solution : how do I detect that the script has been fully loaded and is ready to use ?.
In other words, you'll quickly find that it's impossible to write :
dynamicLoad("showStuff.js");
showStuff("test");
because when you call showStuff(), the dynamically included script is still being loaded, and is not available to use yet !
Load and wait
My first attempt at implementing the "load and wait" functionality was to write an additional function that would call the dynamic loading function and usesetTimeout() to check the availability of a given function a while later.
The result can be found here : dynamic_load.js.
Here's a sample call :
js_include_once_wait( { func:"displayStuff", files:[ "js/displayLib.js", "js/utils.js"] } );
The call uses an object as a parameter. Here are its fields and their meaning :func: name of the function to call where everything is loadedfuncTest(optional) : name of the function whose availability proves that everything is loaded. If not defined,funcTestgets the same values asfuncfiles: array of filenames to load. They will be loaded in the same order as they are declared (I'm using that to manage dependencies). The last file should contain funcTest.
However, the heavy use of setTimeout looks somehow ugly to me. I've just read a piece of code from PHPied that uses JS events but seems to have an issue with Safari. I'll post again when I have made a progress on this...
This post has been completed while listening to :
Voices (Vangelis)


Comments
No comment has been posted yet.