Thursday, June 12th, 2008

ensure: on demand resources

Category: JavaScript, Performance

Omar AL Zabir of Pageflakes.com has posted on ensure, his JavaScript library that provides a handy function ensure which allows you to load JavaScript, HTML, CSS on-demand and then execute your code.

Ensure ensures that relevant JavaScript and HTML snippets are already in the browser DOM before executing your code that uses them.

For example:

javascript

  1. ensure( { js: "Some.js" }, function() {
  2.     SomeJS(); // The function SomeJS is available in Some.js only
  3. });

You can also specify multiple Javascripts, html or CSS files to ensure all of them are made available before executing the code:

javascript

  1. ensure( { js: ["blockUI.js","popup.js"], html: ["popup.html", "blockUI.html"], css: ["blockUI.css", "popup.css"] }, function() {
  2.     BlockUI.show();
  3.     PopupManager.show();
  4. });

Omar says:

Websites with rich client side effects (animations, validations, menus, popups) and Ajax websites require large amount of Javascript, HTML and CSS to be delivered to the browser on the same web page. Thus the initial loading time of a rich web page increases significantly as it takes quite some time to download the necessary components. Moreover, delivering all possible components upfront makes the page heavy and browser gets sluggish responding to actions. You sometimes see pull-down menus getting stuck, popups appearing slowly, window scroll feels sluggish and so on.

The solution is not to deliver all possible HTML, Javascript and CSS on initial load instead deliver them when needed. For example, when user hovers the mouse on menu bar, download necessary Javascript and CSS for the pull-down menu effect as well as the menu html that appears inside the pull-down. Similarly, if you have client side validations, deliver client side validation library, relevant warning HTML snippets and CSS when user clicks the ‘submit’ button. If you have a Ajax site which shows pages on demand, you can load the Ajax library itself only when user does the action that results in an Ajax call. Thus by breaking a complex page full of HTML, CSS and Javascript into smaller parts, you can significantly lower down the size of the initial delivery and thus load the initial page really fast and give user a fast smooth browsing experience.

There is a detailed writeup on how it all works, and it dovetails with the recent performance proposals around when to download resources (sometimes you may not want to wait for on demand loading of course).

Posted by Dion Almaer at 6:18 am
6 Comments

+++--
3.5 rating from 14 votes

6 Comments »

Comments feed TrackBack URI

For the exact same reasons (sluggish pageload etc), I developed a similar function. However, instead of only being able to execute the “remote function” in the callback block (which I assume is the case of ensure), I evaluated the js code in the global scope. I also chose to use synchronous XHR call for this particular function. This had some advantages:

– Once the library (js file) is loaded, its inner functions are executable from anywhere. Even within other js files.
– The library file only loads once and on-demand, after that its in the cache.
– If I want to free up memory in some parts of the system, I can always delete a library from the memory, and if its needed later, it will be re-fetched on-demand.

My start page now loads less than 1 sec, instead of the old 6 seconds (the animated load-screen is now gone).
And its a much cleaner way to have control over smaller js files that loads on-demand, than put them all in one big blob. After all a typical user doesn’t need all the code in the big blob anyway.

Comment by Terje — June 12, 2008

This sounds similar to what Gmail uses to pre-cache css, js and image files. However, I’m not too enthused with the slightly draconian license agreement you need to download the source code. I also wonder why it doesn’t support pre-caching images.

Comment by elfpoet — June 12, 2008

Makes me smile a little … ;-) good work anyway.

Comment by FrankThuerigen — June 12, 2008

@Terje

I’ve tried a similar synchronous approach (I already has a callback based one), but I found that pages loaded slower, due to the browser having to download and eval each script separately, instead of downloading multiple scripts at once, and evaluating them one by one.

my sync ‘require’ function:
http://pastie.textmate.org/213614

my callback one:
http://github.com/urandom/iwl/tree/master/share/jscript/base.js#L496

Comment by urandom — June 12, 2008

Hi Terje,
Ensure does evaluate loaded Javascripts on global scope. It adds a tag to the remote resource and waits until it gets loaded. Then it fires the callback on the given scope. For Safari, which does not support onload/onreadystatechanged, it uses XMLHTTP to load the script.

Good thing about ensure is, it not only loads Javascript but also HTML and CSS. So, you can load a complete sub-module of a website by loading relevant html, js and css in one shot.

Comment by oazabir — June 12, 2008

Ths looks a lot like using.js. But I like the inclusion of CSS lazy loading.

Comment by stimpy77 — June 14, 2008

Leave a comment

You must be logged in to post a comment.