Thursday, September 25, 2008

JavaScript load placement

Bigi Lui.

Programming for the Internet is fraught with a whole host of things that you can't depend on, but for the moment I'll be satisfied with talking about one of them: timing.
Any JavaScript that affects the way a page displays – either its content or its styling – has to first make sure that everything it requires is there i.e. that the page it's working on is downloaded (and parsed). Traditionally (well, for the past couple of years) this requirement has been met in one of two ways: placing an onload function call on the body element, or placing an automatically executed script late in the content of the page. However, these two methods have their disadvantages. Namely, that they can take a while to execute and thereby account for a page flicker where the content is visible before it has been transformed.
To demonstrate this, I've created an example page where a set of tables is hidden using JavaScript and a select box is used to display a particular one. There are four different pages of differing size (content after the tables) and each page has three different methods of running the JavaScript which hides the tables.
The third method is one of my own devising: a scheduling script that runs as soon as the "head" scripts are executed, but which checks to see if the required elements (the tables) exist yet. If they exist they are transformed, if they do not exist the script is scheduled to run after a short wait (1 millisecond), whereby it checks again ... Here's the results:*
Time taken to load JavaScript that hides page elements (Firefox)
Content call
JavaScript scheduler
Small page 1103ms 1081ms 1062ms
Medium page 1128ms 1150ms 1134ms
Large page 1531ms 2621ms 1534ms
Image 11331ms 1849ms 1015ms
Time taken to load JavaScript that hides page elements (IE 6)
Content call
JavaScript scheduler
Small page 2250ms 1644ms 1437ms
Medium page 2199ms 1522ms 1475ms
Large page 2256ms 1566ms 1509ms
Image 12556ms 3050ms 1628ms
*Times were averaged out over 5 attempts for each combination over a 56kb connection. Cache was cleared for each attempt. Timing of execution was initialised by the first script in the "head" and terminated when the function that hides the tables was executed.
At first glance, large differences can be seen in body.onload initialisation between Firefox and Internet Explorer. IE seems to only regard "body" as loaded until after CSS background images have been downloaded, whereas Firefox appears to treat "body" as loaded once its code has been downloaded and parsed.
The filesize of the web pages doesn't appear to affect JavaScript load times too greatly, but it can clearly be seen that the introduction of an image file adversely affects body.onload initialisation. Content calling and scheduling were on a rough par, but improvements could be seen in the scheduler for larger files and images.
Given the poor performance of body.onload under varying circumstances, it would appear that this is not a good option for the initialisation of page transforming JavaScript. Content calls could be an alternative, but they do not guarantee that the required content will be loaded, and they also require alteration of the page content itself. Scheduling of transformation appears to be the safer and faster option, although it still does not prevent flickering of content.


ASP.Net Feeds