Once a month, I lead the Austin JavaScript meetup here in Austin, Texas where we get together, talk shop, show demos of projects, and then have beers at the Draught House. After the first few meetings, Kyle Simpson (@getify) decided to help me out with providing content for the meetups and has provided loads of top-notch quality stuff from his talk on closures and the module programming model to some of his own projects like flxhr.
Recently, Kyle gave a talk on how to download scripts in parallel, something Steve Souders and a few others have discussed how to do effectively. Kyle wrote his own, JavaScript library/framework-agnostic library (for lack of a better term) to allow for parallel script downloading with our without blocking (think dependencies). He presented this project of his at our meetup in June, and thus LABjs was born.
Some History on <script> Tags and Performance
If you’ve ever been to a website like Mashable.com or Marketwatch.com or a slew of other sites that seem to take FOREVER to download even with a high-speed connection, then you’ve probably been the victim of multiple <script> tags blocking the page from fully downloading, and ultimately rendering. Sorry in advance for picking on Mashable, but the home page had a whopping 59 JavaScript requests when I went to it today so it is a perfect candidate for LABjs’s usage, or simply some JavaScript loading optimization of some kind.
So why is this bad? Well, <script> tags, when they download, block other assets from downloading to fully render the page. As a result, a user’s experience with the webpage is severely degraded as that page may take significantly longer to download and subsequently render because the browser is unable to download anything else while the <script> tag is “bogarting” the download queue. Steve Souders provides an excellent demo of this problem here.
Download Without Blocking
So how do we avoid or at least minimize the deterioration of the user experience from the blocking associated with multiple <script> tag requests? That is where LABjs comes in. LABjs, an acronym for “Loading and Blocking JavaScript”, uses well known, yet clever techniques for adding script tags in a manner that allows for non-blocking, parallel downloads.
A quick and easy example of this can be seen in the following code on this demo page.
Upon page load, a quick inspection of the Net tab in Firebug yields the following results:
What should be noted here is how JavaScript files are being downloading not only with other JavaScript files, but images as well. The process could not have been simpler either.
<head> <script type="text/javascript" src="js/LAB.js"> </script> <script type="text/javascript" src="js/load.js"> </script> </head>
In the <head> tag we only need to include the request to the LAB.js library file and then a file I called load.js which contains the following LAB API calls.
$LAB
.script("http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js", "http://www.google-analytics.com/ga.js")
.block(function(){
pageTracker = _gat._getTracker("UA-3312370-2");
pageTracker._trackPageview();
});
If you notice, I am making a call to the script() method passing in a request for the latest version of jQuery and the Google Analytics tracking script. The next is a block() method call that handles my Google Analytics tracking. Even though this example was to show a simple use of the LABjs API, I did add this block of code for my own personal tracking statistics. The block() method call is not required for this example to work.
Downloading with Dependencies
One of the best features that puts LABjs ahead of other methods and frameworks that produce similar results is that LABjs allows for you to load a file, say the latest version of jQuery, and then run some code that is dependent on that file’s existence.
An example of using LABjs with dependencies can be seen in the following code on this demo page.
Upon page load, a quick inspection of the Net tab in Firebug yields the following results:
What is important to note here is the times and places where global.js and the __utm.gif tracking image were downloaded: global.js is dependent on the jQuery library to execute some code and the tracking image is a result of the Google Analytics script executing the tracking code. These files were downloaded (and executed) after their dependent files were fully downloaded, the result of the block() method call. The ease of use and the robustness of dependency management coupled with non-blocking script downloads should be evident with this example.
The Conventional Route
Of course, I have to show the same page using the conventional approach of multiple <script> tags. The demo is here.
Upon page load, a quick inspection of the Net tab in Firebug yields the following results:
As you can clearly see, the blockage from the JavaScript requests denies any other asset from downloading until the JavaScript file has completely downloaded. Even with this simple example, it took 3.43 seconds to render the page as compared to the prior example coming in at only 2.35 seconds a difference of 68.5%. The numerical results themselves should be reason enough to use LABjs.
Where Can I Get It
LAB.js can be found at the humble site, LABjs.com where you can download a zip file of the code with some examples. LABjs is maintained by Kyle himself and he is incredibly responsive to questions or requests so be sure to follow him on twitter.
Tags: JavaScript, labjs, optimization, performance
Browse Timeline
Comments ( 2 )
[...] Joe McCann wrote a great blog post describing and showing off the LABjs tool. [...]
Some Javascript/Ajax projects: “LABjs” and “mpAjax” | the Fresh! added these enlightening words on Jun 29 09 at 1:09 PMReally enjoying this. Thank you for all your hard work. Hopefully I can find something to contribute to the project. Speaking of which, why not put this up on Google code or Git?





