Monday, November 30th, 2009

LABjs gets “Even Faster” with version 1.0

Category: Performance

<p>We have posted about LABjs before, the library that aims to be able to effectively load any script resource(s), from any location, into any page, at any time. It loads them all as parallel as the browser will allow, but maintains execution order when you express the need to do so in the usage of the API, for keeping dependencies safe.

At JSConf.EU in Berlin, I saw Steve Souders and Kyle Simpson riffing on how to make LABjs follow the research that Steve (in his newest book) and Kyle have done.

There were issues in the past, but we now have a new release of LABjs that does the right thing, as long as you wait():

< view plain text >
  1. $LAB
  2. .script("framework.js").wait()
  3. .script("plugin.framework.js")
  4. .script("myplugin.framework.js").wait()
  5. .script("init.js");

Give it a whirl, and read the full post for details on performance and issues with flashing in before behaviour has been added… which leads us to the cavaet on jQuery and DOM ready.

Also, if you think that you should be just concat’ing all of the files into one, see why Kyle thinks you should potentially think again.

As I wrote this another library called NBL came in from “Berklee”. He told us:

The other day I tasked myself with rewriting our company’s website in HTML5 and I really wanted to improve performance all across the board. So after rewriting the HTML and CSS, I looked to JavaScript lazy loading to increase performance. After searching for a small library to do this and not finding anything not requiring jQuery, or unable to handle network timeouts, I decide to write my own non-blocking lazy loader.

It’s called NBL and comes down to 1187 bytes minified. It runs stand-alone and has several options that I could not find in any other library:

1. It can load plugins for your JavaScript framework *after* the framework has been loaded (jQuery is considered the default, but you can override it with any other framework and keep this behaviour).

2. You can provide a callback function that fires when all scripts are loaded, or if you use jQuery, the callback will be fired by jQuery’s document.ready() function (unless the page finishes before jQuery initialises, in which case it fires when all scripts are loaded).

3. In case of network latency (or faulty urls), NBL will fire the callback function after a timeout (by default 1200ms).

4. It does not need to be called, it can be configured completely from the script tag itself, like this:

  1. <script type="text/javascript" src="nbl.js" opt="{ urchin: '',
  2. plugins: [ 'jquery.lightbox.min.js', 'jquery.carousel.min.js' ], ready: my_ready_function }" />

Related Content:


Comments feed TrackBack URI

It’s great to see folks hacking on a general-purpose solution to this, I for one am tired of every framework coming with its own package loader system. Still, I think this is working at too low a level in that you still need to remember each script’s dependencies and the library cannot tell if a script has already been loaded as it has no metadata about what the script contains.

I developed the JS.Class package loader[1] and Helium[2] to hide all these details and let the developer load objects by name rather than by URL — the package loader knows your dependencies so it can figure out cases where downloads can be parallelized, and whether a script has already been loaded.

I think Closure also uses this object detection approach to figure out whether to load scripts, and I find it much more powerful than loading libraries by their URL.


Comment by jcoglan — November 30, 2009

@jcoglan — i completely agree, for complex apps, LABjs represents only the nuts & bolts of a complete solution. I wanted to provide the basic components of a loader that was capable of handling execution-order with parallel downloading, and then what I hope is that people will take LABjs and integrate (or wrap) it with more complex and complete dependency management solutions.
For instance, in a comment thread on the LABjs launch blog post, I suggested some code to how a simple “fallback” mechanism could be wrapped around LABjs to allow you to attempt a load of a file from multiple locations, falling back to subsequent ones if the previous failed (like a CDN and a local fallback, for instance).
I believe and hope that LABjs functionality and API is expressive and powerful enough to suit a variety of needs in dependency management, and hopefully people will start innovating in that respect.
But, for the general website that simply loads 3 or 4 script files (some local, some remote), and then executes some simple initialization logic for the code that was loaded, I believe the API of LABjs will be quite easy to switch from the “<script> tag soup” seen on most sites to a simple and flexible set of calls to LABjs to load the files dynamically.
My main goal is to almost completely make the <script> tag irrelevant and outdated — call it “<script> tags 2.0″ if you will. :)

Comment by getify — November 30, 2009

Here is a similar implementation of an asynchronous sequenced loading script for Mootools. Use it standalone, on functions, and on your Mootools classes:

Comment by csuwldcat — November 30, 2009

the callback will be fired by jQuery’s document.ready() function (unless the page finishes before jQuery initialises, in which case it fires when all scripts are loaded


Comment by Punsons — November 30, 2009

I have bagged on how dynamic script loading makes DOM-ready detection harder (more “suck”), but here’s a different perspective on how LABjs improves DOM-ready. The blessing from the curse, if you will. Just something to keep in mind when thinking about using LABjs.

Comment by getify — December 1, 2009

Leave a comment

You must be logged in to post a comment.