Главная » Hi-Tech » Ускорить сайт с множеством картинок: руководство по отложенной загрузке изображений

Ускорить сайт с множеством картинок: руководство по отложенной загрузке изображений

Перевод материала сооснователя сервиса для оптимизации изображений ImageKit Рахула Нанвани.

В закладки

Аудио

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

Согласно данным сайта HTTP Archive, средний вес страницы на компьютере составляет 1511 КБ. Но изображения часто много весят, и это в первую очередь влияет на размер страницы. Изображения занимают почти 650 КБ, что примерно 45% от общего числа.

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

Основные возможности — вкратце

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

Что такое отложенная загрузка

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

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

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

Инструменты

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

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

В расширении есть раздел, посвящённый закадровым изображениям. С помощью расширения Lighthouse для браузера Google Chrome можно узнать, какие изображения подходят для отложенной загрузки и сколько трафика можно сэкономить.

Также можно использовать анализатор сайтов от ImageKit, чтобы определить, использует сайт отложенную загрузку или нет.

Способы реализации

Сначала рассмотрим более распространённый тег <img>, а затем перейдём к фоновым изображениям CSS. Изображения на странице можно загружать двумя способами — с помощью тега <img> или с помощью CSS-свойства «background», которое позволяет установить одновременно несколько характеристик фона.

Тег <img>

Отложенную загрузку изображений можно разделить на два этапа.

Для изображений, загруженных с помощью тега <img />, браузер использует атрибут тега «src» для запуска загрузки изображения. Шаг первый — предотвратить изначальную загрузку изображения. Если браузер получит атрибут «src», это вызовет загрузку изображения. Не имеет значения, первое это или тысячное изображение в HTML и закадровое ли оно.

Допустим, указываем URL-адрес изображения в атрибуте «data-src» тега «image». Чтобы загрузить изображение через отложенную загрузку, нужно поместить URL-адрес изображения в атрибут «src». Теперь, когда «src» пуст, браузер не начинает загрузку изображения.

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

Загрузка изображений с помощью событий JavaScript

В этом методе используем отслеживание событий прокрутки (scroll), изменения размера (resize), смены ориентации (orientationChange) в браузере.

Проверяем, какие из них теперь находятся в окне просмотра. Когда происходит одно из этих событий, находим все изображения на странице, которые ещё не загружены. Это можно определить с помощью свойств «offset top», «scroll top» и «window height».

Это запускает загрузку изображения. Если изображение вошло в окно просмотра, берём URL из атрибута «data-src» и помещаем его в атрибут «src». После загрузки всех изображений удаляем инструменты для отслеживания событий. Также удаляем класс «lazy», определяющий изображения, которые будут загружаться позже.

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

See the Pen Lazy loading images using event handlers - example code by ImageKit.io (@imagekit_io) on CodePen.

URL-адрес присутствует непосредственно в атрибуте «src» вместо атрибута «data-src». Первые три изображения в примере загружаются заранее. Поскольку эти изображения находятся в верхней части страницы, их следует сделать видимыми как можно скорее. Это необходимо для хорошего пользовательского опыта. Мы не должны ждать события или выполнения JavaScript, чтобы загрузить их.

Загрузка изображений с помощью Intersection Observer API

Он определяет, когда элемент входит в окно просмотра, и начинает действовать. Intersection Observer API — относительно новый API в браузерах. В предыдущем методе приходилось связывать события, учитывать производительность и подсчитывать время появления элемента в окне просмотра.

Intersection Observer API делает процесс проще, помогает избежать вычислений и обеспечивает хорошую производительность.

Ниже — пример использования Intersection Observer API для отложенной загрузки изображений.

Как только это будет сделано, удаляем класс «lazy» из изображения, а также удаляем оттуда обсервер. Как только API обнаруживает, что элемент вошёл в окно просмотра, используя свойство «isIntersecting», выбираем URL из атрибута «data-src» и перемещаем его в атрибут «src», чтобы запустить отложенную загрузку.

See the Pen Lazy loading images using IntersectionObserver - example code by ImageKit.io (@imagekit_io) on CodePen.

Если вы сравните время загрузки изображения двух методов — с отслеживанием событий и Intersection Observer API, — то обнаружите, что с помощью Intersection Observer API загрузка изображения запускается гораздо быстрее, и сайт уже не смотрится «вялым» при скроллинге.

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

Таким образом, приходится возвращаться к методу отслеживания событий в браузерах, где Intersection Observer API не поддерживается. Однако, как и всё новое, поддержка Intersection Observer API доступна не во всех браузерах. Учли этот момент в приведённом выше примере.

Отложенная загрузка фоновых изображений CSS

Для тегов <img /> в браузере простой подход — если URL-адрес изображения доступен, то можно его загрузить. После тегов <img /> фоновые изображения являются наиболее распространённым способом загрузки изображений для страниц.

Чтобы загрузить фоновые изображения CSS, браузер должен создать дерево DOM (объектная модель документа), а также дерево CSSOM (объектная модель CSS), чтобы решить, применяется ли стиль CSS к узлу DOM в текущем документе. С фоновыми изображениями CSS не всё так просто.

Если применяется — загружает. Если правило CSS, определяющее фоновое изображение, не применяется к элементу в документе, то браузер не загружает фоновое изображение.

Так мы обманываем браузер, не применяя свойство CSS «background-image» к элементу, пока этот элемент не попадёт в окно просмотра. Поначалу это может показаться сложным, но такой же принцип лежит в основе техники отложенной загрузки фоновых изображений. Ниже рабочий пример отложенной загрузки фонового изображения CSS.

See the Pen Lazy Loading background images in CSS by ImageKit.io (@imagekit_io) on CodePen.

Мы используем Intersection Observer API, возвращаясь затем к отслеживанию событий. Здесь следует отметить, что код JavaScript для отложенной загрузки остаётся прежним. Хитрость заключается в CSS.

Однако когда класс «lazy» добавляется к этому элементу, в CSS мы переопределяем свойство «background-image» и меняем его на значение «none». Элемент с идентификатором «bg-image» имеет заданное свойство «background-image» в CSS.

Так как по правилам комбинация «bg-image» с «.lazy» имеет более высокое предпочтение в CSS, чем просто «bg-image», браузер применяет свойство «background-image: none» к элементу изначально.

Это изменяет применяемый сейчас CSS и применяет свойство «background-image» к элементу, начавшему загрузку фонового изображения. Когда прокручиваем страницу вниз, the Intersection Observer (или отслеживание событий) определяет, что изображение находится в окне просмотра, и удаляет класс «lazy».

Улучшить пользовательский опыт

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

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

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

1. Правильный дизайн плейсхолдеров

Обычно разработчики используют одноцветный плейсхолдер для изображений или одно изображение в качестве плейсхолдера для всех картинок. Плейсхолдер — то, что отображается на странице до загрузки изображения.

Тем не менее можно сделать лучше. Мы использовали подобный плейсхолдер в нашем примере — везде он выкрашен в сплошной светло-серый цвет. Ниже — примеры использования более удачных вариантов плейсхолдеров.

Плейсхолдер доминирующего цвета

Этот метод давно используется для результатов поиска изображений в Google и Pinterest.

Пример с Manu ninja

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

И это обеспечивает более приятный опыт перехода от плейсхолдера к изображению. Размер изображения-плейсхолдера составляет всего 661 байт, по сравнению с исходным изображением, которое имеет размер 12 700 байт — в 19 раз меньше.

Рабочий пример и код для использования плейсхолдера доминирующего цвета — по ссылке.

Плейсхолдер низкого качества (LQIP)

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

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

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

Рабочий пример и код для использования техники LQIP — по ссылке.

2. Добавление буферного времени

Событие «load image» может сработать с задержкой, как и плейсхолдеры. Часто пользователи быстро прокручивают страницу, и для загрузки и отображения картинки на экране требуется некоторое время. Это плохо влияет на пользовательский опыт.

Решение

Вместо того чтобы загружать изображения только тогда, когда они точно входят в окно просмотра, загрузите картинки, когда они, например, в 500 px от края.

С помощью Intersection Observer API можно использовать параметр «`root`» вместе с параметром «rootMargin» (работает по стандартному принципу поля CSS), чтобы увеличить границы рамки.

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

В этом примере используется пороговое значение 500 px для загрузки изображений.

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

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

Это было сделано в соответствии с тем же принципом: выполнить загрузку немного заранее для лучшего пользовательского опыта. Если не заметили ранее, во всех примерах третье изображение (image3.jpg) всегда загружается сразу, даже если оно находится вне области просмотра.

3. Как избежать смещения содержимого

Если не задать его с помощью CSS, конечный контейнер не будет иметь размеров, то есть его размеры будут равны 0 x 0 px. При отсутствии изображения браузер не знает размеров содержимого, которое должно отображаться в пределах контейнера.

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

Как показано в этом материале Smashing Magazine, смещение контента и видео — довольно неприятный опыт для пользователя.

Решение

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

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

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

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

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

  • Любое изображение, которое присутствует в окне просмотра или в начале страницы, не должно загружаться с помощью отложенной загрузки. Это касается любого изображения-заголовка, рекламных баннеров, логотипов. Пользователь должен видеть их, как только страница загрузится. Помните, что мобильные и десктопные устройства будут иметь разные размеры экрана и, следовательно, разное количество изображений, которые будут видны на экране изначально. Таким образом, необходимо учитывать тип устройства, чтобы решить, какие изображения загружать изначально, а какие нет.
  • Любое изображение, которое частично видно в окне просмотра, не должно загружаться с помощью отложенной загрузки. Это происходит по принципу, который обсуждался выше, — загружать чуть заранее. Любое изображение, находящееся, допустим, в 500 px от области просмотра, может быть загружено заранее.
  • Если страница не длинная, её можно пролистать за несколько движений. Или если за пределами окна просмотра меньше пяти изображений, то отложенную загрузку можно не использовать. Это не принесёт существенной выгоды пользователю с точки зрения производительности. Дополнительный JavaScript, который вы загружаете на страницу, чтобы включить отложенную загрузку, компенсирует выигрыш от отложенной загрузки такого небольшого количества изображений.

Популярные JavaScript-библиотеки

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

  • yall.js (Yet Another Lazy Loader) — использует Intersection Observer API и возвращается к отложенной загрузке на основе событий. Поддерживает все основные типы элементов HTML, но не «background-image». Также работает на Internet Explorer 11 и старших версиях.
  • lazysizes — библиотека с обширной функциональностью. Поддерживает адаптивные изображения «srcset» и атрибут «sizes». Высокая эффективность даже без Intersection Observer API.
  • jQuery Lazy — простая, основанная на jQuery, библиотека отложенной загрузки.
  • WeltPixel Lazy Loading Enhanced — расширение для Magento 2 для отложенной загрузки изображений.
  • Magento Lazy Image Loader — расширение для Magento 1.x для отложенной загрузки изображений.
  • Shopify Lazy Image Plugin — расширение для Shopify для отложенной загрузки изображений. Платная.
  • WordPress A3 Lazy Load — плагин отложенной загрузки изображений для WordPress.

Как проверить, всё ли работает

Перейдите на вкладку «Сеть» → «Изображения». Самый простой способ — открыть инструменты разработчика в браузере Chrome. Здесь при первом обновлении страницы должны загружаться только те изображения, которые должны присутствовать на странице изначально.

Также можно заметить тайминги для загрузки изображения. Затем, когда вы начинаете прокручивать страницу вниз, другие запросы загрузки изображений будут запускаться и загружаться. Это поможет определить проблемы с загрузкой изображений, если таковые имеются, или проблемы с запуском загрузки изображений.

Другой способ — запустить расширение Lighthouse от Google Chrome на странице после внесения изменений и найти предложения в разделе Offscreen images.

Если не работает

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

В треде Stack Overflow рассматриваются проблемы этого тега. Или можно использовать тег <noscript>, чтобы создать удобный интерфейс для этих пользователей. Материал будет полезен для всех, чья целевая аудитория — такие пользователи.


Оставить комментарий

Ваш email нигде не будет показан
Обязательные для заполнения поля помечены *

*

x

Ещё Hi-Tech Интересное!

Сергей Галицкий возглавил список миллиардеров России с наибольшими доходами за 2018 год по версии Forbes

Сергей Галицкий возглавил список миллиардеров России с наибольшими доходами за 2018 год по версии Forbes — Финансы на vc.ru Свежее Вакансии Написать Уведомлений пока нет Пишите хорошие статьи, комментируйте,и здесь станет не так пусто Войти Всего они заработали на продаже ...

PewDiePie уступил место самого популярного YouTube-канала индийскому музыкальному лейблу T-Series

PewDiePie уступил место самого популярного YouTube-канала индийскому музыкальному лейблу T-Series — Соцсети на vc.ru Свежее Вакансии Написать Уведомлений пока нет Пишите хорошие статьи, комментируйте,и здесь станет не так пусто Войти YouTube, каким мы его знали, кончился. В закладки Аудио PewDiePie ...