jQuery: preloading images the right way

Preloading images with jQuery: a well-known and over-discussed topic. But one crucial point in the discussion is still missing: what's the best way to preload images with jQuery? Since performance matters, let's see some of the most used techniques and discuss them.

Basically, preloading images means:

  1. create an array of image paths
  2. loop through the array
  3. create an image element using the corresponding path found in the array.

Here's a solution taken from Snipplr:

$([
	'/path/to/image.png',
 	'/path/to/image.png'
]).each(function(){
		 $('<img/>')[0].src = this;
        new Image().src=this;
});

What's wrong with this code? First of all, the array is not cached in a variable but created on runtime. Second, an Image object is created at the end of the iteration when it's not actually necessary. When a browser creates an image in the DOM, it's necessarily forced to resolve the URI stored in the src attribute. Here this operation is performed twice, thus resulting in a useless double lookup.

A better solution would be:

var paths = ['/path/to/image.png', '/path/to/image.png'],
    i,
    len = paths.length,
    d = document;
    
for(i = 0; i < len; i++) {

	var path = paths[i];
	var img = d.createElement('img');
	img.src = path;

}

We've avoided the each() method because it's too expensive in terms of performance. We've also cached the array, its length and the document object. Then we've created all the images using DOM core methods which are faster than non-native jQuery methods.

Don't forget to put all your code within the callback function of the load() method on the window object:

$(window).load(function() {

	var paths = ['/path/to/image.png', '/path/to/image.png'],
    i,
    len = paths.length,
    d = document;
    
for(i = 0; i < len; i++) {

	var path = paths[i];
	var img = d.createElement('img');
	img.src = path;

}
	

});

The code must be executed just before the DOMContentLoaded event is triggered.

Back to top