Предварительная загрузка/кеширование изображения jQuery

Короче говоря, у меня очень большая фотогалерея, и я пытаюсь кэшировать как можно больше эскизных изображений, когда загружается первая страница. Может быть более 1000 эскизов.

Первый вопрос - глупо пытаться предварительно загружать/кэшировать многие?

Второй вопрос - когда срабатывает функция preload(), весь браузер перестает отвечать на минуту до двух. В этот момент срабатывает обратный вызов, поэтому предварительная нагрузка завершена. Есть ли способ выполнить "интеллектуальную предварительную загрузку", которая не мешает пользователю/скорости при попытке загрузить много объектов?

Функция $.preLoadImages берет здесь: http://binarykitten.me.uk/dev/jq-plugins/107-jquery-image-preloader-plus-callbacks.html

Вот как я его реализую:

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

1000 изображений много. Я слишком много спрашиваю?

Ответ 1

После просмотра этой предварительной загрузки script, кажется, что script не дождался загрузки одного изображения, прежде чем переходить к следующему. Я считаю, что это то, что заставляет ваш браузер зависать - вы, по сути, говорите браузеру, чтобы одновременно загрузить сотню изображений.

Лучше всего использовать рекурсивную функцию, чтобы начать загрузку следующего изображения только после завершения первого. Вот простой пример, который я собрал.

Изменить: это вызывает ошибки, см. новую версию ниже.

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!"); });
});

И снова важно, чтобы вы только заставляли браузер загружать одно изображение за раз. Больше, чем это, и вы рискуете заблокировать браузер до тех пор, пока все не закончите.

-

Изменить: Новая версия без рекурсии. Я тестировал этот массив с массивом 1000+ и не встречал никаких ошибок. Моя идея заключалась в том, чтобы заменить рекурсию интервалом и логическим; Каждые 50 миллисекунд, мы опросили функцию и спросили "что-нибудь погрузка?". Если ответ отрицательный, мы продолжим и поставим в очередь следующее изображение. Это повторяется снова и снова, пока все это не закончится.

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);
};

Мне все еще любопытно, как это будет выглядеть, насколько это возможно, на полной веб-странице с большим количеством других вещей. Сообщите нам, как это происходит.

Ответ 2

Это интересный вопрос о производительности. Как это работает в Firebug или в инструментах разработчика Chrome при предварительной загрузке? Это заставляет меня думать, что это было бы хорошим использованием Lazy Load Plugin.

Lazy loader - это плагин jQuery, написанный в JavaScript. Это задерживает загрузку изображений в (длинных) веб-страницах. Изображений вне видимости (видимая часть веб-страница) не загружается перед пользователем прокручивает к ним. Это противоположно предварительная загрузка изображений.