Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery image preload/cache halting browser

In short, I have a very large photo gallery and I'm trying to cache as many of the thumbnail images as I can when the first page loads. There could be 1000+ thumbnails.

First question -- is it stupid to try to preload/cache that many?

Second question -- when the preload() function fires, the entire browser stops responding for a minute to two. At which time the callback fires, so the preload is complete. Is there a way to accomplish "smart preloading" that doesn't impede on the user experience/speed when attempting to load this many objects?

The $.preLoadImages function is take from here: http://binarykitten.me.uk/dev/jq-plugins/107-jquery-image-preloader-plus-callbacks.html

Here's how I'm implementing it:

$(document).ready(function() {
    setTimeout("preload()", 5000);
});
function preload() {
    var images = ['image1.jpg', ... 'image1000.jpg'];
    $.preLoadImages(images, function() { alert('done'); });
}

1000 images is a lot. Am I asking too much?

like image 893
Nathan Loding Avatar asked Jun 15 '10 02:06

Nathan Loding


1 Answers

After looking over that preload script, it appears that the script does not wait for one image to load before moving on to the next. I believe this is what causes your browser to hang - you're essentially telling the browser to load a hundred images all at the same time.

A better way would be to use a recursive function to start loading the next image only after the first one is done. Here is a simple example I put together.

Edit: This one causes stack overflow errors, see new version below.

var preLoadImages = function(imageList, callback) {
    var count = 0;
    var loadNext = function(){
        var pic = new Image();
        pic.onload = function(){
            count++;
            if(count >= imageList.length){
                callback();
            }
            else{
                loadNext();
            }
        }
        pic.src = imageList[count];
    }
    loadNext();
};

$(document).ready(function(){
    var files = ['file1,jpg', 'file2.jpg'];
    preLoadImages(files, function(){ alert("Done!"); });
});

Again, the important thing here is to make sure you are only forcing the browser to download one image at a time. Any more than that and you risk locking the browser up until they're all finished.

--

Edit: New version sans recursion. I tested this one with a 1000+ item array and didn't encounter any errors. My idea was to replace the recursion with an interval and a boolean; Every 50 milliseconds, we poll the function and and ask "anything loading?" If the answer is no, we'll go ahead and queue up the next image. This repeats over and over until its all done.

var preLoadImages = function(imageList, callback) {
    var count = 0;
    var loading = false;
    var loadNext = function(){
        if(!loading){
            loading = true;
            count++;
            pic = new Image();
            pic.onload = function(){
                loading = false;
                if(count >= imageList.length-1){
                        clearInterval(loadInterval);
                        callback();
                }
            }
            pic.src = imageList[count];
        }
    }
    var loadInterval = window.setInterval(loadNext, 50);
};

I'm still curious how this will do, performance wise, on a full webpage with lots of other stuff going on. Let us know how it goes.

like image 116
Greg W Avatar answered Oct 02 '22 12:10

Greg W