Статьи

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

Эта статья является частью серии, созданной в сотрудничестве с SiteGround . Спасибо за поддержку партнеров, которые делают возможным использование SitePoint.

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

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

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

Что такое ленивая загрузка?

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

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

Ленивая загрузка в действии на Unsplash.com

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

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

  • Если ваш веб-сайт использует JavaScript для отображения содержимого или предоставления пользователям какой-либо функциональности, загрузка DOM быстро становится критической. Сценарии обычно ждут, пока DOM полностью загрузится, прежде чем они начнут работать. На сайте со значительным количеством изображений, отложенная загрузка — или загрузка изображений асинхронно — может иметь значение для пользователей, которые остаются или покидают ваш сайт.
  • Поскольку большинство решений для отложенной загрузки работают, загружая изображения только в том случае, если пользователь прокрутил до места, где изображения будут видны внутри области просмотра, эти изображения никогда не будут загружены, если пользователи никогда не достигнут этой точки. Это означает значительную экономию полосы пропускания, за что большинство пользователей, особенно тех, кто имеет доступ к Интернету на мобильных устройствах и медленных соединениях, будут благодарить вас.

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

Там нет идеального пути.

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

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

# 1 Ленивая загрузка с использованием API Intersection Observer

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

Вот как MDN представляет этот API:

API Intersection Observer предоставляет способ асинхронно наблюдать изменения в пересечении целевого элемента с элементом-предком или с областью просмотра документа верхнего уровня.

Другими словами, асинхронно прослеживается пересечение одного элемента с другим.

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

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

<img data-src="image.jpg" alt="test image"> 

Обратите внимание, что путь к изображению содержится внутри атрибута data-src , а не атрибута src . Причина в том, что использование src означает, что изображение будет загружаться сразу, а это не то, что вам нужно.

В CSS вы даете каждому изображению значение min-height , скажем, 100px . Это дает каждому заполнителю изображения (элемент img без атрибута src) вертикальное измерение.

 img { min-height: 100px; ...more styles here } 

В документе JavaScript вы затем создаете объект config и регистрируете его в экземпляре intersectionObserver :

 // create config object: rootMargin and threshold // are two properties exposed by the interface const config = { rootMargin: '0px 0px 50px 0px', threshold: 0 }; // register the config object with an instance // of intersectionObserver let observer = new intersectionObserver(function(entries, self) { // iterate over each entry entries.forEach(entry => { // process just the images that are intersecting. // isIntersecting is a property exposed by the interface if(entry.isIntersecting) { // custom function that copies the path to the img // from data-src to src preloadImage(entry.target); // the image is now in place, stop watching self.unobserve(entry.target); } }); }, config); 

Наконец, вы перебираете все свои изображения и добавляете их в этот экземпляр iterationObserver:

 const imgs = document.querySelectorAll('[data-src]'); imgs.forEach(img => { observer.observe(img); }); 

Достоинства этого решения: его легко реализовать, он эффективен, а intersectionObserver выполняет тяжелые вычисления.

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

Вы можете узнать больше об API Intersection Observer и подробностях этой реализации в статье Дениса .

Прогрессивная ленивая загрузка Робина Осборна # 2

Робин Осборн предлагает превосходное решение, основанное на прогрессивном совершенствовании . В этом случае сама ленивая загрузка, которая достигается с помощью JavaScript, считается улучшением по сравнению с обычным HTML и CSS.

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

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

Эта техника имеет ряд преимуществ:

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

Вы можете узнать все подробности подхода Робина Осборна в его блоге .

# 3 Lozad.js

Быстрая и простая альтернатива реализации отложенной загрузки изображений — позволить библиотеке JS выполнить большую часть работы за вас.

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

Вы можете включить Lozad в npm / Yarn и импортировать его, используя выбранный вами пакет модулей:

 npm install --save lozad yarn add lozad 
 import lozad from 'lozad'; 

Кроме того, вы можете просто загрузить библиотеку с помощью CDN и добавить ее в конец HTML-страницы в виде < script> < script> < script> тег:

 <script src="https://cdn.jsdelivr.net/npm/lozad/dist/lozad.min.js"></script> 

Далее, для базовой реализации, добавьте класс lozad в ресурс в вашей разметке:

 <img class="lozad" data-src="img.jpg"> 

Наконец, создайте экземпляр Lozad в вашем документе JS:

 const observer = lozad(); observer.observe(); 

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

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

Только помните о поддержке браузера и, в конце концов, интегрируйте эту библиотеку с polyfill для API Intersection Observer.

# 4 Ленивая загрузка с эффектом размытого изображения

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

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

Размытое изображение заполнителя на сайте Medium.

Размытое изображение заполнителя на сайте Medium.

Высокое разрешение, ленивое загруженное изображение на веб-сайте Medium.

Высокое разрешение, ленивое загруженное изображение на веб-сайте Medium.

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

Моя любимая техника Крейга Баклера. Вот все достоинства этого решения:

  • Производительность: всего 463 байта CSS и 1 007 байтов минимизированного кода JavaScript
  • Поддержка экранов сетчатки
  • Без зависимости: не требуется jQuery или другие библиотеки и фреймворки
  • Постепенно улучшается, чтобы противодействовать старым браузерам и отказавшим JavaScript

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

# 5 Yall.js

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

При включении Yall в ваш документ вам нужно инициализировать его следующим образом:

 <script src="yall.min.js"></script> <script> document.addEventListener("DOMContentLoaded", yall); </script> 

Далее, для ленивой загрузки простого элемента img , все, что вам нужно сделать в разметке:

 <img class="lazy" src="placeholder.jpg" data-src="image-to-lazy-load.jpg" alt="Alternative text to describe image."> 

Обратите внимание на следующее:

  • Вы добавляете класс ленивый к элементу
  • Значение src является заполнителем изображения
  • Путь к изображению, которое вы хотите лениво загрузить, находится внутри атрибута data-src .

Среди преимуществ Yall:

  • Отличная производительность благодаря API Intersection Observer
  • Фантастическая поддержка браузера (восходит к IE11)
  • Никаких других зависимостей не требуется.

Чтобы узнать больше о том, что может предложить Yall, и о более сложных реализациях, не стесняйтесь заглянуть на страницу проекта на GitHub .

Вывод

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