One of the most important features of modern web sites overall, is their ability to respond quickly and come back with the information requested by the user. We live in an “attention economy” on the Web 2.0, and if your site does not respond pretty much instantly, the user will find a site that does.
One way that modern sites achieve this, is by loading in smaller increments – for example, loading the detailed content for an item on a list can be deferred using AJAX.
Doing this in a compatible and clean way, can be tricky.
Let’s look at some of the requirements that a good solution to this problem must fulfill.
Secondly, we target all modern browsers – and therefore, our solution must be fully cross browser , targeting Internet Explorer 6 through 8, Firefox, Opera and Chrome, and hopefully any other standards compliant future browsers.
Another concern is notification of resource readiness. Since resources are loaded asynchronously, and sometimes have already been loaded once, our script needs to provide a callback-notification when the resource is ready and available.
And finally, we don’t want to write code for every project to keep track of what’s been loaded and what has not. In other words, we need a load-once method, so that classes, widgets and stylesheets can be automatically loaded the first time they are needed.
We’re going to accept certain limitations of this script.
For one, we’re not going to attempt to do a lot of error handling – if a resource can’t be loaded, this is a problem that needs to be solved by the developer, and not really something you can provide a “pretty” solution for anyway.
And secondly, some resource management scripts attempt to inject scripts in a way that allows scripts from foreign domains to run without security limitations. This has certain other drawbacks that I won’t get into, but we’re going to assume that you’re loading scripts from your own domain.
Our script comes in the form of a classless singleton object, which provides two methods for loading resources on demand:
Loader.load( url, [callback-function], [context-object], [driver-name] ); Loader.once( url, [callback-function], [context-object], [driver-name] );
The Loader.once() method will ensure that the same resource is only loaded once. Note that the callback will be called when the resource is ready , not only the first time when the resource actually loads.
Arguments for the two functions are identical:
- callback-function : optional callback-function – called when the resource (and any resources requested before it) has loaded.
- context-object : optional object to use as the context (this) for the callback-function. Use null (or leave out) if calling context is unimportant.
- driver-name : optional driver-name, e.g. “css” or “js” – this determines how the loaded resource is handled. If unspecified, the loader will try to determine the driver by file-extension, but will default to “js” if the file extension at the end of the URL does not match “.css” or “.js”.
When you need to load a collection of resources, remember that they will be loaded in the order you request them. For example, loading components for a widget-based framework such as ExtJS is possible – you can load a component class declaration, and then load another class that extends it, but you must request them in order.
Another thing to keep in mind, when you need to know when a collection of resources are ready, you don’t need to attach a callback to every request – just attach your callback-function to the last request, as this won’t execute until all previously requested resources are ready.
Finally, here is the source code for you to cut and paste: