Sunday 7 October 2007

Optimizing Javascript - Load and wait

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 use setTimeout() 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 loaded
  • funcTest (optional) : name of the function whose availability proves that everything is loaded. If not defined, funcTest gets the same values as func
  • files: 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
Voices (Vangelis)

Sunday 30 September 2007

A sigh of relief

I recently came across an essay by Paul Graham, entitled Holding a Program in One's Head. If you ever worked as a developer in a profit-driven company, you'll be pleased to read this controversal paragraph near the end of his essay :

Perhaps it will help if more people understand that the way programmers behave is driven by the demands of the work they do. It's not because they're irresponsible that they work in long binges during which they blow off all other obligations, plunge straight into programming instead of writing specs first, and rewrite code that already works. It's not because they're unfriendly that they prefer to work alone, or growl at people who pop their head in the door to say hello. This apparently random collection of annoying habits has a single explanation: the power of holding a program in one's head.

That thought enlightened my day when I first read it, because it makes it all very clear with simple words. Book writers may need an adequate atmosphere or state of mind to be able to write properly. Programmers just need one thing that they aren't even provided with in some places : the means to focus.

That said, it is not an excuse for any programmer to behave like a caveman and hug his code even tighter after having read that paper. Our salvation definitely doesn't lie in the software we're crafting, no matter how technically beautiful it might become. Building a wall between you and the rest of the company for the sake of Perfect Coding is one of the best ways to annihilate any hope of professional progress.

I invite you to read the other texts as well, like this essay about consumerism. The man definitely knows what he's talking about.


This post has been completed while listening to :

Ghost in the Shell Stand Alone Complex - OST 3
Ghost in the Shell Stand Alone Complex - OST 3 (Yoko Kanno)