Быстрая и плавная загрузка изображений — это одна из немаловажных составляющих хорошего веб-интерфейса. Кроме того, появляется все больше сайтов, использующие крупные фотографии в дизайне, таким проектам особенно важно следить за корректной загрузкой графики. В этой статье описано несколько техник, которые помогут контролировать загрузку изображений.
Использование контейнера для каждого изображения
Простой способ, который можно применить к любому изображению на сайте. Заключается в том, что каждая картинка оборачивается в DIV, который предотвращает построчную загрузку:
<div class="img_wrapper">
<img src="comicbookguy.jpg" alt=""/>
</div>
С помощью контейнера можно контролировать соотношение сторон картинки, а также использовать индикатор загрузки, что очень удобно, если изображения тяжелые.
Например, чтобы задать соотношение сторон 4:3, можно использовать следующий CSS:
.img_wrapper{
position: relative;
padding-top: 75%;
overflow: hidden;
}
.img_wrapper img{
position: absolute;
top: 0;
width: 100%;
opacity: 0;
}
Для того, чтобы изображение отображалось в браузере только после полной подгрузки, необходимо добавить событие onload для изображения и использовать JavaScript, который будет обрабатывать событие:
<div>
<img src="comicbookguy.jpg" alt="" onload="imgLoaded(this)"/>
</div>
function imgLoaded(img){
var $img = $(img);
$img.parent().addClass('loaded');
};
Код функции внутри тега HEAD должен быть расположен в самом конце, после любого jQuery или другого плагина. После полной подгрузки изображения его необходимо показать на странице:
.img_wrapper.loaded img{
opacity: 1;
}
Для эффекта плавного появления картинки можно использовать CSS3 transition:
.img_wrapper img{
position: absolute;
top: 0;
width: 100%;
opacity: 0;
-webkit-transition: opacity 150ms;
-moz-transition: opacity 150ms;
-ms-transition: opacity 150ms;
transition: opacity 150ms;
}
Живой пример этого способа можно посмотреть на Codepen.
Использование контейнера для множества изображений
Предыдущий способ хорошо подходит для отдельных изображений, а что если на странице их много, например галерея фотографий или слайдер? Подгружать сразу все нецелесообразно — картинки могут много весить. Для решения этой проблемы можно заставить JavaScript'ом загружать только нужные в данный момент времени изображения. Пример HTML-разметки для слайдшоу:
<div id="Slideshow">
<img src="slide_1.jpg" alt="" onload="slideLoaded(this)" />
<img src="slide_2.jpg" alt="" onload="slideLoaded(this)" />
<img src="slide_3.jpg" alt="" onload="slideLoaded(this)" />
</div>
Используем функцию slideLoaded(), чтобы контролировать процесс:
function slideLoaded(img){
var $img = $(img),
$slideWrapper = $img.parent(),
total = $slideWrapper.find('img').length,
percentLoaded = null;
$img.addClass('loaded');
var loaded = $slideWrapper.find('.loaded').length;
if(loaded == total){
percentLoaded = 100;
// INSTANTIATE PLUGIN
$slideWrapper.easyFader();
} else {
// TRACK PROGRESS
percentLoaded = loaded/total * 100;
};
};
Подгруженным изображениям присваивается класс loaded, а также отображается общий прогресс. И снова, JavaScript должен быть помещен в конец тега HEAD, после всего остального.
Кэширование
На графически тяжелых сайтах можно в фоновом режиме, незаметно для пользователя, загружать изображения в кэш браузера. Например, есть многостраничный сайт, на одной из внутренних страниц которого есть много графического контента. В этом случае будет целесообразно подгружать изображения в кэш еще до того, как пользователь перешел на нужную страницу. адреса картинок в массиве:
<script>
var heroArray = [
'/uploads/hero_about.jpg',
'/uploads/hero_history.jpg',
'/uploads/hero_contact.jpg',
'/uploads/hero_services.jpg'
]
</script>
Когда посетитель заходит на сайт, после загрузки главной страницы, начинают загружаться изображения в кэш. Для того, чтобы кэширование не мешало отображению текущего контента, необходимо функционал JavaScript добавить в событие window load:
function preCacheHeros(){
$.each(heroArray, function(){
var img = new Image();
img.src = this;
});
};
$(window).load(function(){
preCacheHeros();
});
Такой способ улучшает удобство использования сайта, однако дает дополнительную нагрузку на сервер. Это нужно иметь в виду при внедрении подобного функционала. Кроме того, необходимо обязательно учитывать возможные пути посетителей на сайте и кэшировать изображения, расположенные на страницах, которые пользователь вероятнее всего посетит. Чтобы понять такие пути по сайту, необходимо анализировать статистику посещаемости.
Загрузка по событию
способ заключается в том, что изображения начинают подгружаться после определенного события. Это увеличивает производительность и экономит трафик пользователя. HTML-разметка:
<div class="img_wrapper lazy_load">
<img
src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"
data-src="comicbookguy.jpg"
alt="Comic Book Guy"
/>
</div>
Стоит заметить, что URL изображение задано в data-src, а не в src. Это необходимо, чтобы браузер не загружал картинку сразу. Вместо этого в src загружается прозрачный пиксель в GIF, заданный в base64, что уменьшает количество обращений к серверу.
Остается только при нужном событии изменить значение src на data-src. JavaScript позволяет загружать изображения постепенно:
function lazyLoad(){
var $images = $('.lazy_load');
$images.each(function(){
var $img = $(this),
src = $img.attr('data-src');
$img
.on('load',imgLoaded($img[0]))
.attr('src',src);
});
};
$(window).load(function(){
lazyLoad();
};
Заключение
Нет одного оптимального способа для того, чтобы управлять загрузкой изображений на сайте. В каждом конкретном случае необходимо выбирать подходящий метод, а также комбинировать несколько, если это целесообразно. Одними из главных моментов, на которые необходимо обратить внимание — это производительность и трафик. Проще говоря, в первую очередь стоит подумать о том, как будет удобнее пользователю сайта.
Автор: grokru