Короче говоря, у меня есть очень большая фотогалерея, и я пытаюсь кэшировать столько изображений миниатюр, сколько я могу, когда первая страница загружается. Мог быть 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'); });
}
1 000 изображений много. Я спрашиваю слишком много?
После просмотра этого сценария предварительной загрузки выяснилось, что сценарий не ждет загрузки одного изображения, прежде чем перейти к следующему. Я считаю, что это то, что заставляет ваш браузер зависать - вы, по сути, говорите браузеру загружать сотню изображений одновременно.
Лучшим способом было бы использовать рекурсивную функцию, чтобы начать загрузку следующего изображения только после того, как будет выполнено первое. Вот простой пример, который я собрал.
Изменить: это вызывает ошибки переполнения стека, см. Новую версию ниже.
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);
};
Мне все еще любопытно, как это будет происходить с точки зрения производительности на полной веб-странице с множеством других вещей. Сообщите нам, как это происходит.
Это интересный вопрос производительности. Как это работает в Firebug или Chrome Developer Tools, когда вы предварительно загружаете все это? Это наводит меня на мысль, что это было бы хорошим использованием Lazy Load Plugin.
Lazy loader - это плагин jQuery, написанный на языке на JavaScript. Он задерживает загрузку изображений на (длинных) веб-страницах. Изображения вне области просмотра (видимой части веб-страницы) не будут загружены до того, как пользователь прокрутки до них. Это противоположно предварительной загрузки изображений.