prototype-based image preloader
Preloading images is often a final optimization step when writing a javascript heavy web app. I think its generally because its seen as a pita, so it keep getting pushed as the site is developed until you get to the very end, and something has to be re-engineered to make it look right. I think that’s a shame, because a simple preloader is pretty easy to write and use and can really improve the look & feel of a website. Here’s mine:
var Preloader = { load: function() { var args = $A(arguments); var callback = Object.isFunction(args.last()) ? args.pop() : Prototype.emptyFunction; var urls = Object.isArray(args[0]) ? $A(args[0]) : args; var loaded = 0; var images = $A(); var onload = function() { if (++loaded == urls.length) { callback(); // cleanup images.each(function(i) { delete i }); images = callback = urls = null; } }; urls.each(function(url) { var image = new Image(); image.onload = image.onerror = onload; image.src = url; images.push(image); }); } };
To use you load it up with url’s like:
// to load a single image Preloader.load('http://futureadapter.com/wp-content/uploads/2008/08/fa_blog3-1.jpg'); // to load a bunch of images Preloader.load('http://futureadapter.com/wp-content/uploads/2008/08/fa_blog3-1.jpg', 'http://futureadapter.com/another_image.jpg'); // or, alternately, if it works better for loading a bunch of images Preloader.load(['http://futureadapter.com/wp-content/uploads/2008/08/fa_blog3-1.jpg', 'http://futureadapter.com/another_image.jpg']);
And the final argument can be a callback which executes after all the images have been loaded. You’d commonly use this for something like:
// show an ajax spinner in your front end over the updating area $('target').startWaiting(); new Ajax.Request('/images', { method: 'get', onSuccess: function(response) { // grab the image data from the back end var images = response.responseJSON['images']; var urls = images.invoke('public_filename'); // load up the images Preloader.load(urls, function() { // when all the images have been loaded, replace the // existing ones with the new page (for instance) $$('#target .image').each(function(image, index) { image.writeAttribute('src', urls[index]); }); // and reveal the updated area with the new images $('target').stopWaiting(); }); } });
Have fun!





