Шаг 2 реализация предварительной загрузки изображений. Управляем загрузкой изображений. Предзагрузка изображений с помощью новых возможнестей HTML5

Для того чтобы можно было загружать на сервер один или несколько файлов, в форме применяется специальное поле. В браузерах Firefox, IE и Opera такой элемент отображается как текстовое поле, рядом с которым располагается кнопка с надписью «Обзор...» (рис. 1). В Safari и Chrome доступна только кнопка «Выберите файл» (рис. 2).

Рис. 1. Вид поля для загрузки файла в Firefox

При нажатии на кнопку открывается окно для выбора файла, где можно указать, какой файл пользователь желает использовать.

Синтаксис поля для отправки файла следующий.

Атрибуты перечислены в табл. 1.

Прежде, чем использовать данное поле, в форме необходимо сделать следующее:

  • задать метод отправки данных POST (method="post" );
  • установить у атрибута enctype значение multipart/form-data .
  • Форма для загрузки файла продемонстрирована в примере 1.

    Пример 1. Создание поля для отправки файла

    HTML5 IE Cr Op Sa Fx

    Отправка файла на сервер

    Хотя можно установить ширину поля через атрибут size , в действительности ширина никак не влияет на результат работы формы. В браузерах Safari и Chrome этот атрибут вообще никакого воздействия не оказывает.

    Атрибут multiple более важен, он позволяет не ограничиваться одним файлом для выбора, а указать их сразу несколько для одновременной загрузки.

    Если атрибут accept не указывать, тогда добавляются и загружаются файлы любого типа. Наличие accept позволяет ограничить выбор файла, что особенно важно, когда требуется загрузить только изображение или видео. В качестве значения выступает , несколько значений разделяются между собой запятой. Также можно использовать следующие ключевые слова:

    В табл. 2 показаны некоторые допустимые значения атрибута accept .

    Использование дополнительных атрибутов показано в примере 2.

    HTML5 IE 10+ Cr Op Sa Fx

    Загрузите ваши фотографии на сервер

    Не все браузеры поддерживают новые атрибуты. IE полностью игнорирует multiple и accept , Safari не поддерживает accept , а Firefox не работает с MIME-типом, только с ключевыми словами. Поэтому в примере выше специально для Firefox установлено значение image/*,image/jpeg . Также учтите странную ошибку в Опере, она не допускает пробелы после запятой внутри accept .

    Результат примера показан на рис. 3. Обратите внимание, что из-за наличия multiple несколько изменился вид поля.

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

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

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

    1. Загрузка каждого изображения в отдельности (Single-Asset)

    Это методика, которую можно применить к любому или ко всем изображениям своего сайта для предотвращения (или хотя бы скрытия) традиционной построчной загрузки базовых JPG’ов. Мы начнем с упаковки каждого изображения в div с классом img_wrapper:

    < div class = "img_wrapper" >

    < img src = "comicbookguy.jpg" alt = "" / >

    < / div >

    Этот упаковщик предоставит нам некоторое дополнительное управление размерами наших изображений и их коэффициентом пропорциональности, чего не может гарантировать простой тэг img. Он также даст возможность применить спиннер загрузки – либо как фоновое изображение, либо как отдельный элемент – который после окончания загрузки изображения можно скрыть.

    Для этого примера ограничим свое изображение коэффициентом пропорциональности 4:3 – очень важно для адаптивных сайтов. Обратите внимание, что мы также скрыли изображение с помощью opacity: 0;, что дает нам возможность управлять тем, как и когда мы его увидим при наступлении нужного момента.

    Img_wrapper{ position: relative; padding-top: 75%; overflow: hidden; } .img_wrapper img{ position: absolute; top: 0; width: 100%; opacity: 0; }

    Img_wrapper {

    position : relative ;

    padding - top : 75 % ;

    overflow : hidden ;

    Img_wrapper img {

    position : absolute ;

    top : 0 ;

    width : 100 % ;

    opacity : 0 ;

    Каждая картинка в DOM запускает событие load, когда все его данные загружены с сервера, а само изображение отображено браузером. Чтобы захватить и привязать это событие, нам понадобится использовать JavaScript. Я начну с добавления атрибута onload к тэгу изображения.

    < div >

    < img src = "comicbookguy.jpg" alt = "" onload = "imgLoaded(this)" / >

    < / div >

    К сведению новичков, еще не видевших ничего подобного – это называется встроенным атрибутом скрипта, и позволяет нам привязать функциональность JavaScriptа прямиком к событиям, запускаемым из элементов DOM, что во многом сходно с добавлением стилей напрямую к элементам с помощью встроенного атрибута style. Верьте или нет, но в начале развития Веба эти встроенные атрибуты скрипта занимали значительную часть написания JavaScript’а и, подобно встроенным стилям, осуждаются в наши дни борцами за чистоту кода и семантику.

    Поэтому те из вас, кто испытывает отвращение при виде встроенного JavaScriptа и уже готов пуститься наутек, пожалуйста, задержитесь и поверьте мне на слово, что это все еще единственный самый эффективный и надежный метод захвата события load изображения в DOM. Хотя я целиком и полностью выступаю за прогресс и HTML5 – я не имею совершенно ничего против применения приемов старой школы, если они элегантны и функциональны.

    Альтернативой этому является индивидуальная привязка события load к каждому изображению в document ready. Однако проблема возникает, когда изображения загружаются прежде запуска document ready, и до того, как у нас появляется возможность привязать функциональность к событию загрузки каждого изображения. Отдельная проблема, когда изображения уже кэшированы браузером с предыдущей сессии, и загружаются мгновенно. Мы пропускаем событие, а наша функция не вызывается. У атрибута onload отсутствуют такие проблемы, потому что он, так сказать «предварительно привязан» к событию и поэтому обрабатывается, когда браузер анализирует HTML.

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

    При добавленном атрибуте onload в момент загрузки изображения будет вызываться функция imgLoaded(). Ее нужно поместить в файл javascript в head самой страницы (после jQuery, если вы его применяете в своей функции, и после любых остальных плагинов) с тем, чтобы она компилировалась до парсинга body и загрузки изображений. Если вставить функцию внизу страницы, высока вероятность того, что изображения станут грузиться до определения функции.

    С помощью ключевого слова this мы можем послать необработанный объект DOM изображения в свою функцию JavaScript в качестве аргумента:

    function imgLoaded(img){ var $img = $(img); $img.parent().addClass("loaded"); };

    function imgLoaded (img ) {

    var $ img = $ (img ) ;

    $ img . parent () . addClass ("loaded" ) ;

    Или простым JavaScript’ом:

    function imgLoaded(img){ var imgWrapper = img.parentNode; imgWrapper.className += imgWrapper.className ? " loaded" : "loaded"; };

    function imgLoaded (img ) {

    var imgWrapper = img . parentNode ;

    imgWrapper . className += imgWrapper . className ? " loaded" : "loaded" ;

    С помощью javascriptа можно быстро пройти по DOM на один уровень вверх и добавить к содержащему элементу упаковщика класс loaded. Я уверен, вы согласитесь с тем, что это удивительно элегантное решение. Выборочно назначив этому классу стили, можно теперь показать свое загруженное изображение, установив его непрозрачность на 1:

    Img_wrapper.loaded img{ opacity: 1; }

    Img_wrapper . loaded img {

    opacity : 1 ;

    Чтобы процесс происходил гладко, мы добавим к img несколько переходов CSS3 и добьемся при загрузке своего изображения эффекта «постепенного проявления».

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

    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.io, включающий альтернативную версию с отображением спиннера загрузки.

    Прогрессивные JPGи

    В качестве примечания к этой технике и в ответ на некоторые полученные мною к этой статье отзывы, определенно стоит упомянуть «прогрессивные» JPG’и. Это еще одна давняя методика родом из 1990-х, затрагивающая сохранение JPG’ов как «прогрессивных», а не «обычных» с целью предотвращения построчной загрузки – а вместо нее покадрово прорисовывая изображения одной высоты по мере его загрузки. Основное преимущество этого приема состоит в том, что он предотвращает «скачки» прибывающего контента по странице при загрузке изображений.

    Раздражают ли такие эффекты, как спиннеры загрузки и постепенное проявление – это дело личного вкуса, но в основном прием с упаковывающим div’ом решает эти проблемы с помощью минимума CSS и JavaScript’а .

    В применении техники упаковывающего div’а лучше всего то, что можно не волноваться по поводу изменения высоты изображений по мере их загрузки, а также не нужно обрекать своих пользователей на уродливое объединение пикселей в группы, что, по моему мнению, может для пользователя оказаться настолько же раздражительным, как и обычная загрузка. К тому же она ничего не стоит – процесс повторного отображения рисунка по нескольку раз на самом деле создает дополнительную нагрузку на маломощные мобильные устройства. Раздражают ли такие эффекты, как спиннеры загрузки и постепенное проявление – это дело личного вкуса, но в основном прием с упаковывающим div’ом решает эти проблемы с помощью минимума CSS и JavaScript’а, и отсутствует необходимость полагаться на пользователя (в ситуации с CMS) при сохранении JPG’ов определенным способом.

    2. Пакетная загрузка нескольких изображений

    Вышеописанная техника очень хороша для отдельных изображений, но как быть, если у нас есть подборка изображений, которые нужно отобразить в «карусели» или слайдшоу, или если мы пользуемся плагином разметки вроде Masonry? Обычная ошибка при использовании плагинов «карусели»/слайдера – их обработка при document ready, зачастую до загрузки всех их изображений. Это может вызвать переход слайдшоу к пустому, еще не загрузившемуся изображению, особенно если мы имеем дело с фотографиями с высоким разрешением и большим размером файла.

    Для предупреждения этого явления нужно подвергать обработке предпочитаемый вами плагин только тогда, кoгда все необходимые изображения уже загрузились. Применив вариацию вышеприведенной техники, мы снова добавим атрибут onload ко всем изображениям своего слайдшоу:

    NB: Нижеприведенная разметка приводится только как упрощенный примерный вариант разметки плагина слайдшоу, и должна быть адаптирована в соответствии с вашими требованиями.

    < 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 >

    В JavaScript’е мы применим функцию 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; // ИНИЦИАЛИЗИРУЙТЕ ПЛАГИН $slideWrapper.easyFader(); } else { // ОТСЛЕДИТЕ ПРОЦЕСС percentLoaded = loaded/total * 100; }; };

    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 ;

    // ИНИЦИАЛИЗИРУЙТЕ ПЛАГИН

    $ slideWrapper . easyFader () ;

    } else {

    // ОТСЛЕДИТЕ ПРОЦЕСС

    percentLoaded = loaded / total * 100 ;

    Каждый раз при загрузке материала мы добавляем к нему класс loaded для слежения за его прогрессом.
    С помощью последнего if мы инициализируем плагин (в данном случае jQuery EasyFader), когда количество изображений с классом loaded равно общему количеству изображений в контейнере. В качестве дополнительного свойства можно разделить переменную loaded на переменную total и использовать ее для визуализации прогресса для пользователей: путем либо отображения процентного соотношения, либо используя ее для управления шириной индикатора выполнения, или другим подобным образом.

    И снова, этот скрипт должен быть помещен в head вашего документа, после jQuery и того плагина, который вы будете подвергать обработке, когда готов.

    3. Предварительное кэширование изображений для быстродействия

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

    Например, скажем, у меня есть многостраничный сайт, где у каждой второстепенной страницы есть вверху изображение в высоком разрешении. Вместо того, чтобы заставлять пользователя ждать время загрузки всех этих изображений каждый раз при переходе на отдельную страницу, можно загрузить их в кэш до того, как пользователь попадет на страницу. Давайте начнем с помещать их URL’ы в массив:

    var heroArray = [ "/uploads/hero_about.jpg", "/uploads/hero_history.jpg", "/uploads/hero_contact.jpg", "/uploads/hero_services.jpg" ]

    var heroArray = [

    "/uploads/hero_about.jpg" ,

    "/uploads/hero_history.jpg" ,

    "/uploads/hero_contact.jpg" ,

    "/uploads/hero_services.jpg"

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

    Когда пользователь зайдет на домашнюю страницы моего сайта, я дождусь ее полной загрузки, перед тем, как что-то делать, чтобы убедиться, что я не прерываю загрузку контента самой страницы, добавляя сторонюю загрузку. Для этого, я прикреплю функциональность JavaScript’а к событию window load, запускающемуся только когда весь контент страницы уже загружен и отображен (включая изображения), в отличие от события document ready, которое запускается, как только готов DOM:

    function preCacheHeros(){ $.each(heroArray, function(){ var img = new Image(); img.src = this; }); }; $(window).load(function(){ preCacheHeros(); });

    function preCacheHeros () {

    $ . each (heroArray , function () {

    var img = new Image () ;

    img . src = this ;

    } ) ;

    $ (window ) . load (function () {

    preCacheHeros () ;

    } ) ;

    Или простым JavaScript’ом:

    function preCacheHeros(){ for(i = 0; i < heroArray.length; i++){ var url = heroArray[i], img = new Image(); img.src = url; }; }; window.onload = preCacheHeros();

    function preCacheHeros () {

    for (i = 0 ; i < heroArray . length ; i ++ ) {

    var url = heroArray [ i ] ,

    img = new Image () ;

    img . src = url ;

    window . onload = preCacheHeros () ;

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

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

    Имеет смысл рассмотреть аналитику вашего сайта до внедрения предварительного кэширования

    Прекогнитивное предварительное кэширование

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

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

    Это известно как прекогнитивное предварительное кэширование, где мы используем статистические данные своей аналитики для предсказания поведенческих шаблонов перемещения наших пользователей по сайту. Возможно, звучит несколько фантастично, но вы удивитесь тому, насколько точно можно предсказать поток посетителей и превратить его в свое (и пользователей) преимущество.

    Возможно, звучит несколько фантастично, но вы удивитесь тому, насколько точно можно предсказать поток посетителей

    4. «Ленивая» загрузка изображения для снижения нагрузки на сервер

    Понятие lazy-loading относится к изображениям, загружаемым программным путем после специального события, чтобы запретить браузеру запрашивать и отображать все изображения на странице как только документ загружается.

    В основном применяется в длинных или перегруженных изображениями страницах. На целевой странице блога Barrel мы сочетаем «ленивую» загрузку с плагином MixItUp для того, чтобы гарантировать, что изображения, отсутствующие в текущем фильтре или странице, не станут загружаться без особой в том нужды, пока этот элемент не станет видимым. Любые изображения, подлежащие «ленивой» загрузке, мы снова обернем в div с классом img_wrapper, которому в свою очередь зададим класс lazy_load для того, чтобы можно было легко их выбрать с помощью jQuery:

    ) . load (function () {

    lazyLoad () ;

    Вышеприведенная функция «лениво» загружает все изображения после запуска события window load, но код внутри цикла.each() можно адаптировать так, чтобы он подходил к множеству ситуаций. Очень распространенное его применение – прикрепить к событию window scroll и «лениво» загружать изображения по мере их прокрутки до окна просмотра.

    Вперед, к загрузке изображений

    В процессе экспериментирования с парой этих методик над множеством проектов в течение последних примерно 12 месяцев мне пришлось по-настоящему сократить и отточить их для применения в недавно переделанном проекте barrelny.com (выпущенном обратно в свет в апреле), где я применял сочетание всех четырех методов для того, чтобы обеспечить грациозную загрузку изображений, пытаясь при этом выжать каждую унцию производительности из экстремально перегруженного фотографиями и изображениями вебсайта. Путем комбинирования предварительного кэширования и «ленивой» загрузки с загрузкой страниц при помощи AJAX, слайдшоу и постраничной разбивкой на стороне клиента мы смогли создать отличное впечатление гладкости и всего сайта.

    Пытаясь сделать выжимку из этих приемов для презентации команды разработчиков Barrel, я был приятно удивлен тем, насколько легковесны все эти методики на бумаге – обычно 5-10 строк кода в jQuery – и как легко их внедрить в любой проект. Кроме того, каждуя из них можно написать простым JavaScript’ом без лишних хлопот и дополнительного кода, но если вы пользуетесь jQuery, как это часто делаем мы, определенно следует воспользоваться преимуществами его надежных методик прохода DOM.

    Эти приемы, несомненно, являются единственным способом выполнения их соответствующей функциональности, но их можно легко адаптировать под существующие каркасы-фреймворки и плагины. Если вы еще не обдумывали загрузку изображений, надеюсь, что сделаете это сейчас! Почему бы не применить один-два из них в своем следующем проекте?

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

    В своё время для таких целей я и искал хороший прелоадер, но так и не смог найти решения, которое бы меня полностью удовлетворяло. Пришлось написать свой.

    В нём есть базовый функционал, позволяющий выполнять две основные функции: загружать изображения и вызывать после этого коллбэк. Но так же есть и свои фичи. Он может загружать картинки по очереди в том порядке, в котором они были помещены в массив. Не только по одному, а по два-три-N. А на каждую итерацию загрузки может выполнять коллбэк. Но и это ещё не всё: после загрузки последнего изображения выполнится финальный коллбэк, говорящий о том, что все изображения загружены.

    Использование

    Существует два варианта использования jQuery.preload.
    Первый — передавать адрес(а) изображений:

    $.preload(images, , );

    • images
      Адрес изображения на вход можно подавать как строкой (для одной картинки), так и массивом.
    • part
      Далее идет необязательный параметр, указывающий по сколько изображений загружать за раз. 0 — значит все разом, значение по умолчанию.
    • callback
      Ну и наконец коллбэк — функция, которая выполнится по завершении загрузки изображения. Ей можно указать свой параметр last , принимающий значение true , если эта часть последняя.

    Второй вариант использования — загружать все изображения и фоновые картинки в элементе:

    $("#elem").preload();

    • callback
      Функция, которая выполнится после загрузки всех изображений.
    Примеры
    • — изображения будут загружаться по одному, после загрузки каждого сработает коллбэк, а после загрузки последнего сработает финальный коллбэк.
    • — коллбэк отображает ранее скрытые, но уже загруженные изображения.

    Для корректной работы плагина требуется jQuery версии 1.6 или выше.

    Изображения, хорошие и качественные, являются главным преимуществом сайта. Но основной бедой в использовании изображений является их размер: обычно это не менее 50% от размера сайта и не менее 300 Кб на каждой странице составляются изображения (такой объем информации на мобильном телефоне загружается примерно 1,5 секунды, на стационарном компьютере - 0,2-0,3 секунды).

    Что же с ними делать?

    Последовательные изображения и PNG

    Проблема с размером изображений является уже очень старой и хорошо изученной. Лучшее, что вы можете сделать прямо сейчас, - это использовать progressive (последовательные) JPEG формат для полноцветных изображений (фотографии) и PNG формат для всех других файлов (например, фоновых изображений или иконок).

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

    PNG формат за счет максимального сжатия палитры и представления индексированных изображений (с небольшим количеством цветов) может передать даже большое по площади изображение при помощи небольшого объема информации. Это крайне критично для эффективности вашего сайта: если вы не можете ухудшить качество представления информации, то в состоянии свести размер этой информации к минимуму.

    «Ленивая» загрузка (lazy load)

    Следующим шагом в оптимизации размера загружаемой информации стала загрузка изображений, необходимых только для отображения первого экрана сайта. Например, если у вас каталог с десятками позиций, а на первом экране помещается всего 8 - разумно загрузить сначала только 8 изображений. Это (визуально) сильно ускорит полную загрузку страницы сайта. А когда пользователь покручивает страницу дальше - то загружать все изображения для дальнейших частей страницы. При этом показывать индикатор загрузки на месте загружаемых изображений.

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

    Непростая задача, правда?

    Улучшаем lazyload

    Существует несколько реализаций lazyload - в частности, unveil - которые обошли первый недостаток: загрузка изображений может быть отложена ровно до того момента, когда мы покажем пользователю «готовый» сайт (обычно это момент готовности структуры страницы - DOMready - но иногда и полная загрузка страницы - onload). И начнем загружать все изображения сразу после этого события. Если пользователь потратит 2-3 секунды на первичное ознакомление с содержимым страницы, то для него загрузка изображений пройдет практически незаметно (браузер уже покажет, что страница готова). Если пользователь все же успеет начать просматривать страницу до того, как у него загрузятся все изображения, то на месте изображений вместо значка от браузера по умолчанию или пустого места будет индикатор загрузки.

    Вполне элегантное решение, но его можно улучшить еще, если более тщательно подойти к последовательности загрузки страниц сайта. Рассмотреть, какие виджеты и когда загружаются: чтобы они не вклинились в процесс загрузки изображений. Расположить изображения на 1-2 поддоменах, если их больше 30 - так будет положительных эффект от параллельной загрузки изображений. Возможно, часть изображений перенести на событие полной загрузки, а часть - на событие готовности структуры страницы. В общем, исследовать процесс загрузки сайта более детально и оптимизировать пользовательское восприятие - чтобы сайт выглядел реактивным.

    Пред-загрузка изображений (prefetch)

    Техническое сообщество на этом не остановилось и пошло в оптимизации процесса загрузки изображений дальше. Что если мы можем предугадать следующее пользовательское действие на сайте - и сразу загрузить требуемые ресурсы (а смые значительные из них - это изображения)? Как это можно сделать?

    Техника предварительной загрузки изображений (preload или prefetch) активно используется в различных галереях изображениях - например, Яндекс.Фотки - пока вы просматриваете одно изображения, браузер уже загружает два-три предыдущих и два-три следующих. И покажет их практически моментально после перехода назад или вперед. И это будет реактивно!

    Для интернет-магазина можно использовать ту же технику при просмотре отдельных товаров - подгружая сразу изображения из галереи или похожих товаров из рекомендательного сервиса. Это сократит объем передаваемой информации от сайта к пользователю после перехода по новой ссылке и визуально ускорит сайт.

    Заключение и список действий

    Итак, масса полезной информации. Что же конкретно делать? Вам нужно пройти по следующему списку и проверить, все ли у вас на сайте хорошо. Если нет - то принять соответствующие меры:

  • Полноцветные изображения создаются в последовательных JPEG? Если нет и можно сохранять изображения с потерями качества, то нужно настроить этот формат.
  • Все остальные изображения в PNG? Если нет, то нужно настроить именно этот формат. Дополнительно рекомендуется оптимизировать PNG изображения пакетно или при помощи сервисов .
  • Все ли изображения отображаются в естественных размерах? Часто физические размеры (высота и ширина) у изображения больше размера видимого изображения. Это приводит к рудиментам по качеству и заставляет загружать значительно больше данных, чем нужно. Измените размеры изображений к используемым на сайте (если нужно, создайте дубликаты в других размерах).
  • Изображений на странице больше 20 и они не помещаются на первых двух экранах? Нужно использовать какое-либо решение lazyload для сокращения объема первоначально загружаемой информации.
  • На сайте кроме изображений используется несколько виджетов и кодов статистики? Проверьте диаграмму загрузки сайта и убедитесь, что ценные изображения при отложенной загрузке передаются пользователю в первую очередь.
  • Нужно максимально ускорить сайта, и все пункты уже сделаны? Настройте предварительную загрузку изображений при переходах по страницам сайта. Изучите сценарии использования сайта - и подстройте логику загрузки изображений под них.
  • Это, в принципе, все. Стоит напомнить, что Айри автоматически приводит изображения к минимальному размеру и наилучшему формату без потери качества, а также может динамически выставить правильные размеры для изображений и отложить их загрузку.

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

    С анимацией дела обстоят еще хуже. Представьте, например, что вам нужно реализовать на JS (JQuery) проезжаюшую легковую машину, заменяюшуюся через 2 секунды автобусом. Изображения с машиной и автобусом разные. При этом они начнут подгружаться только в тот момент, когда браузер получит на них ссылку с возможностью подгрузки (то есть в начале анимации ). На загрузку такой картинки нужно будет несколько секунд. То есть получается, что половину двухсекундной анимации это изображение только будет подгружаться - это не порядок.

    Но это все можно исправить предзагрузкой (предварительной загрузкой ) изображений, которая позволяет подгружать картинку в буфер сразу при загрузке основной страницы (или даже перед этим ). Об этом я и хочу рассказать в данной заметке.

    Предзагрузка картинок на JavaScript (JQuery)Вариант с загрузкой на JS, как мне кажется, один из самых лучший, особенно если вы имеете дело с анимацией. Его суть в том, что вы просто посредством JavaScript создаете копию картинки и загружаете её в буфер браузера, тем самым при необходимости уже не нужно будет подгружать картинку, так как она уже будет предварительно загружена .

    Сложно звучит? =) А выглядит всего лишь вот таким кодом, где нужно заменить путь к картинке на свой и все будет работать:

    //создаем JQuery функцию, которая будет подгружать изображения в буфер jQuery.preloadImages = function() { for(var i = 0; i < arguments.length; i++) { jQuery("").attr("src", arguments[ i ]); } }; //указываем путь к изображению, которое нужно подгрузить $.preloadImages("/tpl/testimg.png");


    Если же вам нужно подгрузить несколько изображений, то вы просто можете перечислить их через запятую, вот так:

    $.preloadImages("imageone.jpg", "dirname/imageok.jpg", "/tpl/testimg.png");


    Картинок может быть любое количество. Главное не забывайте про JQuery функцию, без нее предзагрузка работать не будет.

    У этого способа есть и недостатки, например в том, что он зависит от того, включен ли JS в браузере пользователя. Но по личному опыту скажу, что если равняться на тех, у кого выключен JS, то в современных технологиях сайтостроения очень много не удастся реализовать. Да и таких юзеров, я думаю, не так уж много. Вообще нужно равняться на большинство, а большинство не кастомизирует браузер до такой степени.

    Я лично во многих проектах предпочитаю использовать именно такой способ подгрузки ввиду того, что он удобен в реализации.

    Предзагрузка изображений с помощью новых возможнестей HTML5Этот способ появился относительно недавно ввиду того, что сама технология HTML5 была запущена не так давно. Суть его в том, что вы проставляете ссылку на картинку через тег link, а в атрибуте rel (тип подгружаемого элемента ) вы прописываете, что это предзагрузка. Тем самым браузер видит этот тег и автоматически загружает в буфер картинку .

    Делается это добавлением в html код вот такого тега (только ссылку на изображение меняете на свою ):


    Здесь в rel прописано 2 параметра: prerender - для его величества Chrome и prefetch - для остальных браузеров. Если вы хотите подгружать большее число картинок, то копируете тег и заменяете ссылку нужное количество раз:

    Плюс этого способа в том, что отключение JS никак не повлияет на предзагрузку, но лично я вижу 2 явных недостатка:
    1) Технология HTML5, а значит и этот способ предзагрузки, поддерживается далеко не всеми браузерами. Сейчас, правда, браузеры обновляются и большинство современных развивающихся браузеров распознают HTML5, но всеравно это еще далеко от идеала.
    2) Более грамоздкий в отличае от JS реализации, ведь придется каждое изображение описывать отдельным тегом (причем с разными параметрами rel, что бы добиться чего-то близкого к кроссбраузерности ).

    В общем считаю, что этот способ перспективен, но ему нужно время. Сейчас в нем не хватает универсальности .

    Предварительная загрузка картинок на проверенном временем HTMLСамая первая идея, которая приходит обычно в голову на чистом html - это создать div блок с параметром CSS "display:none;" , в нем картинку и это должно стать предзагрузкой. На самом деле это не работает, браузер начнет загрузку в буфер только тогда, когда display станет отличное от none.

    Но я придумал способ с использованием хитростей CSS. Расскажу подробнее про него.

    Размещение в невидимом блоке через CSS opacity и position (позиционирование)В CSS есть такое свойство - opacity . Его предназначение - менять прозрачность и изменить прозрачность можно вплоть до нуля. Кроме того, в CSS есть еще и свойство position, которое нужно для позиционирования элемента на странице (можно попиксельно сдвигать блок с информацией хоть куда в пределах и за пределы видимости страницы ). Все это нам и пригодится:

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

    Если вы хотите сделать прелоад нескольких картинок таким способом, то достаточно их указать внутри div блока, вот так:

    Вот такие способы предзагрузки картинок/изображений можно использовать в разработке сайтов. Если у Вас есть еще какие-то идеи, то рад буду их почитать в комментариях.
    Всем удачи в верстке и создании анимации! =)



    Есть вопросы?

    Сообщить об опечатке

    Текст, который будет отправлен нашим редакторам: