Javascript Preloader

The year was 2006. I was knee deep building websites with Flash and when I say Flash, I actually mean ActionScript. Fast forward to 2013 and guess what? Javascript today is pretty much what ActionScript was in 2006, at least, from a language point of view.

Anyway, I was working on this website recently and it had about 5 meg’s of graphics to load on just the home page. We wanted things to be smooth and instead of having images being loaded onto the page when ever the browser decided to load ‘m, we wanted to preload them into browser cache so that when they were needed on the page they would pretty much load instantly.

Since I had done this sort of stuff in ActionScript about a gazillion times before I decided to create a simple preloader class, this time in Javscript:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
/**
 * Simple asset preloader class.
 *
 * @dependency: delegate
 */
function Preloader( assets, callback ) {
   this.assets = assets;
   this.asset = null;
   this.assetIndex = 0;
   this.callback = callback;
   this.loadNextAsset();
};
 
Preloader.prototype.loadNextAsset = function() {
   this.onupdate( 100 / this.assets.length * this.assetIndex );
 
   if( this.assetIndex >= this.assets.length ) {
      return this.callback.call();
   }
 
   this.asset = new Image();
   this.asset.onload = delegate(this, this.loadNextAsset);
   this.asset.src = this.assets[ this.assetIndex++ ];
};
 
Preloader.prototype.onupdate = function( percentage ) {
   // Default, do nothing.
};

As you can see. This is pretty straight forward. It basically cycles through all the assets provided to it sequentially and after the last asset is loaded it will trigger an event. I’ve added an extra event to capture a percentage loaded in case needed (I did).

One thing to point is that this Preloader class has a dependency on a “delegate” helper function. This helper function makes sure that functions are called in the correct context, preserving scope etc. Don’t forget to include it otherwise the above won’t work:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/**
 * Delegates callbacks while maintaining object scope.
 */
function delegate(scope, method) {
   if(arguments.length > 2) {
      var args = [];
      var numOfArgs = arguments.length;
      for(var i=2; i<numOfArgs; i++) {
         args.push(arguments[i]);
      }
      return function() { return method.apply(scope, args); }
   } else {
      return function() { return method.call(scope); }
   }
}

To actually use the preloader, simply specify a list of assets in the form of an array:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function onPreloadDone() {
   // Preload complete.
}
 
$(document).ready( function() {
   var assets = [
      "http://www.mydomain.com/assets/big-image.jpg",
      "http://www.mydomain.com/assets/other-big-image.jpg"
   ];
 
   var preloader = new Preloader( assets, onPreloadDone );
   preloader.onupdate = function( percentage ) {
      // percentage is between 0 and 100. You might want to round it.
   }
} );

That’s all there is to it. Happy preloading!

This entry was posted in Programming. Bookmark the permalink. Both comments and trackbacks are currently closed.