Preloading Images with jQuery and JavaScript

Creating effects on websites using jQuery and other JavaScript has really grown from flashy extras to full on applications in the browser. Part of slick applications is images. They might be part of the content being loaded or something like an icon in an application. But, for those images being added after the page is loaded there can be a time gap while that image is downloaded. To avoid those time delays the images can be preloaded in the background. Lets take a look at how to do that.

A jQuery Script

Here is a simple jQuery script to preload the images.

(function($) {
  var cache = [];
  // Arguments are image paths relative to the current page.
  $.preLoadImages = function() {
    var args_len = arguments.length;
    for (var i = args_len; i--;) {
      var cacheImage = document.createElement('img');
      cacheImage.src = arguments[i];
      cache.push(cacheImage);
    }
  }
})(jQuery)

You'll notice that this isn't anything special to jQuery. You can change the name from $.preLoadImages() to some other function name and use this outside of jQuery.

To use the preloading make a call like:

jQuery.preLoadImages("image1.gif", "/path/to/image2.png");

Breaking Down The Script

Let's break down this snippet of code to see what's happening.

(function($) { ... })(jQuery)

We are wrapping the code in an anonymous function and passing jQuery in with a $ alias. This is described in the jQuery plugin authoring documentation. The reason for doing this is to avoid conflicts with other scripts that may be in the page.

var cache = [];

Inside the anonymous function we have a variable to cache the images we load. The images may not be preloaded if they are just loaded locally inside $.preLoadImages(). This is due to some broswers garbage collection cleaning up local variables.

$.preLoadImages = function() {

The reason this is attached to jQuery is to avoid cluttering the global namespace. If you aren't using jQuery in the page or have an application global object it may be better to attach it there.

var args_len = arguments.length;

We are going to use the length (number) of arguments in a loop. If we use arguments.length in the loop it will calculate the number of arguments on each pass through the loop. We only need to do this once so we store the length in a variable.

for (var i = args_len; i--;) {
  ...
}

Here we loop through all the arguments and act on each one. We are not worried about the order the images are preloaded so we are loading them from last to first. Loops that count down are faster than loops that count up.

var cacheImage = document.createElement('img');
cacheImage.src = arguments[i];
cache.push(cacheImage);

We create an image as a DOM element in the browser. In some other scripts jQuery('<img>') is used to create the image. This will work but it much slower than using the DOM. Once the image is created set the src to the path of the image and attach it to the cache array.

Special thanks to Nathan Smith for reviewing and tweaking the code.