JavaScript: Dynamic binding and lazy loading

For a project I’m working on at the moment I have a requirement to be able to transparently switch between implementations of APIs that my W3C Widgets use based on the user’s context.

For example, if the Widget wants to send an SMS message, if the user is accessing the Widget in a mobile phone it should use the phone’s SMS sending facility using the W3C Messaging API. However, if its being used on a laptop, usually we would want to send it to a server-side SMS gateway with a script that implements the same API.

Another example is to be able to switch the publish-subscribe implementation without changing any client code – e.g. from a Faye server to Apache Qpid or something like Pusher.

As I’ve been using a lot of Node lately I was taken with the CommonJS approach to loading JavaScript modules, and wondered if this could also be applied to client-side JavaScript. In Node, to load a required library you use something like:

var thing = require("thing");

There are some similar capabilities on the client side, such as the JQuery Lazy Loading module and Ryan Grove’s LazyLoad. These typically inject new <script> tags into the HTML document’s <head> tag as the page is rendered (Google’s Ajax Loader works the same way).  In some cases loading the scripts will block the page loading process, but in others the page loading continues normally, in which case you need to use a callback for when your script has loaded. For example:

LazyLoad.js('http://example.com/foo.js', function () {
  alert('foo.js has been loaded');
});

This is pretty close to what I’m after, all I need now is to make sure I can load scripts based on a module name rather than the URL of the script using a resolution service, and also to export the public interface of the loaded script. The end result would be:

loader.load("test", function(test){
   test.helloWorld()
});

So here my loader is going to resolve “test” to a script URL, lazy load it, and then pass the exported API of “test” to the callback method. To export the API I can use the CommonJS convention of having a global exports object, and attach an object with the module name to it. So in this case, my implementation of test can include “exports.test = new TestImpl()”, and the loader can call “eval(“exports.”+library);” to access it.

I don’t yet have a service registry built, or a way of collecting important context information to send it, but I can at least mock it up for now, and you can look at my code here to see where I’m up to with it.

Now I have a basic implementation I’m starting to wonder when I shouldn’t dynamically bind my APIs in this way given it adds a lot of useful flexibility. I think the key consideration is going to be the effect on page loading times and responsiveness of applications which is something I’m going to have to test.

About these ads
This entry was posted in development, javascript, widgets. Bookmark the permalink.

2 Responses to JavaScript: Dynamic binding and lazy loading

  1. Pingback: Inter-widget communication | Scott's Workblog

  2. Pingback: Adventures in progressive enhancement | Scott's Workblog

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s