NetBen Ramblings about JavaScript and frontend development.

19Nov/10Off

Code on demand

Ever inserted JavaScript libraries in the wrong order? Annoying isn't it? Next to being a little bit irritating, it also prevents some possibilities like async loading. This can be fixed by simply writing your code to be "on demand" friendly. The concept is so blatantly obvious and at first you will scratch your head at the given examples thinking "what's he on about", but you'd be amazed how often people simply don't do it.

A JavaScript goes through two stages when loaded:

  1. evaluation
  2. interpretation/execution

Evaluation can be considered compilation, it simply translates JavaScript to something the browser can run. Interpretation is a runtime stage where code is actually executed where it needs to be executed. Consider the following two .js files

// file: x.js
var x = {
   message : "Hello world"
};
// file: y.js
var y = x.message;
function shout(){
   alert( y );
};

If y.js is loaded before x.js, there will be an "Object not found" or "undefined doesn't have property message" exception, the order of your files are significant and other then refactoring, the only option you have is to simply put the files in the right order. Furthermore when using a dynamic script loader such as RequireJS, you will have to do some extra work to shoehorn your files in the right order still.

The solution is "on demand" coding.

// file: x.js
var x = {
   message : "Hello world"
};
// file: y.js
var y;
function shout(){
   y || ( y = x.message );
   alert( y );
};

What has changed other then having more code? First, the y variable is set when you need it rather then when y.js file is loaded and interpreted. There's still an order issue but it's less painful and best of all, your scripts are now compatible with RequireJS without the need of extra work to maintain interpretation order.

Consider the following RequireJS usage:

require( [ "y.js" , "x.js" ] , function(){
   shout();
});

This will/can break with the first example since y.js can be interpreted before x.js. However with the "on demand" example, the order became meaningless, so it will work just fine with minimum effort.

Consider another circumstance:

<script src="y.js"></script>
<script src="x.js"></script>
<script>
   window.onload = function () {
      shout();
   }
</script>


This will most certainly break with the first example ( "Object not found" exception ), but again, it will work perfectly fine with the "on demand" example. A little change and your code becomes a heck more robust.

Now why is this important to write about? Well firstly a lot of JavaScript libraries are written with dependency resolving at interpretation time. jQuery and plugins using other plugins springs to mind, even jQueryUI does this when you use an exploded (not concatenated) version. If you ever plan to start using a dynamic script loader, this will simply give you headaches, whereas if they where all written in the "on demand" way, it would be compatible right from the get go.

I seriously hope people will read this, understand the concept and write more robust scripts/plugins/widgets and whatnot. It will create a lot nicer mashup environment up until everyone writes their code the define() way.

Filed under: JavaScript Comments Off
Comments (2) Trackbacks (1)
  1. What is the difference between

    y || (y = x.message);

    and

    y = y || x.message;

    The second form seems more easily readable to me.

  2. Both are premature optimisations to begin with.
    The first does 1 action less when y is truthy, namely the assignment.
    The second always does the assignment, whether y is truthy or falsy.
    The difference in performance is minute tbh…

    I always tend to use the first because it’s usually inside a function that gets called a lot.