Unblock The Tubes

Most websites built today use JavaScript. It is an essential building block of the web along with HTML & CSS. However, when it comes to performance JavaScript has one problem… it Blocks The Tubes™!

When CSS and images are included in your HTML, they are loaded asynchronously. This is not the case with JavaScript. When a JavaScript file is loaded, no other resources will be downloaded.

In terms of performance, most developers right now follow this rule: CSS at the top, JavaScript at the bottom. This allows all CSS & images to be loaded asynchronously, before it hits the roadblock of JavaScript, but at least by that point you have all your resources, so as soon as JavaScript is finished your page will be displayed.

However, there are alternatives available that allow JavaScript to be loaded asynchronously. These methods are documented here by Steve Soulders, but the main problem with this is it means a fair amount of work to implement… a developer must architect his or her code specifically to allow it to be loaded in this manner.

Over the last few weeks, there has been some progress in bringing one of the techniques (Script DOM Element) to the masses.

Analyze This!

First off, and probably the easiest way for a developer to get into asynchronous JavaScript loading, Google launched asynchronous tracking code for Google Analytics.

As Google Analytics uses JavaScript to collect usage data, it usually adds more load time to each page it is installed on, and can potentially cause pages to hang, if there are issues with Google’s servers. But with the following code, this issue goes away:

<script type="text/javascript">
var _gaq = _gaq || [];
  _gaq.push(['_setAccount', 'UA-XXXXX-X']);
  _gaq.push(['_trackPageview']);

(function() {
    var ga = document.createElement('script');
    ga.src = ('https:' == document.location.protocol ? 'https://ssl' :
        'http://www') + '.google-analytics.com/ga.js';
    ga.setAttribute('async', 'true');
    document.documentElement.firstChild.appendChild(ga);
  })();
</script>

Just replace the UA-XXXXX-X with your own identfier.

To see an example of this, just have a look at the source code of this site.

Straight From The Lab

Another project that has been emerging to tackle this same issue is LABjs.

From the LABjs documentation, the following code shows how one might use it:

$LAB
.script("framework.js").wait()
.script("plugin.framework.js")
.script("myplugin.framework.js").wait()
.script("init.js");

The wait() bit would be where you want the browser to block, everything else would be loaded asynchronously.

I’m sure the LABjs project will evolve a lot over the next few months, but it’s an interesting start… one to keep your eye on.

Reblog this post [with Zemanta]