Детальное описание техники ленивой загрузки изображений (Lazy Load)

Ленивая (или отложенная) загрузка картинок – это популярный метод асинхронного обращения к адресу изображения, по мере необходимости его загрузки, а не сразу после того, как HTML страницы был проанализирован браузером. Вы, скорее всего, уже видели эту реализацию в действии, поскольку этот метод используется на многих популярных сайтах.

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

Обратной стороной медали является то, что графические элементы и медиа-данные (картинки, видео, аудио) – это очень «тяжелые» файлы, которые замедляют скорость загрузки страницы.

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

 

Сегодня мы рассмотрим следующие пункты:

  • Что такое ленивая загрузка (Lazy Load) изображений и как она работает?
  • Теория реализации отложенной загрузки
  • Практические примеры достижения отложенной загрузки:
    • с помощью событий JavaScript
    • с помощью API Intersection Observer
  • Зависимость отложенной загрузки от JavaScript
  • Популярные JavaScript библиотеки для ленивой загрузки
  • Как протестировать отложенную загрузку?

 

Вот что мы будем сегодня реализовывать:

 

 

 

Что такое ленивая загрузка (Lazy Load) изображений и как она работает?

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

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

 

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

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

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

 

Эффективность техники ленивой загрузки

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

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

 

 

Теория реализации отложенной загрузки

Типичная HTML-разметка для изображения выглядит так:

<img src="/{путь к картинке}/image.jpg?x55427" />

 

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

Соответственно, первая задача для достижения отложенной загрузки – это предотвратить загрузку изображений. Чтобы отложить загрузку, нужно поместить URL-адрес изображения в атрибут, который отличается от src. Допустим, если для этих целей мы будем использовать атрибут data-src, тогда код будет выглядеть так:

<img data-src="/{путь к картинке}/image.jpg?x55427" />

 

Теперь, когда атрибут src пустой, браузер не будет запускать загрузку изображения.

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

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

 

 

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

Рассмотрим практические примеры достижения отложенной загрузки для изображений.

 

Способ №1: Отложенная загрузка изображения с помощью событий JavaScript

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

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

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

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

Вот рабочий пример этого подхода:

<style>
/* заполнитель для картинок */img {
 background: #ccc;
 width: 1920px;
 height: 1080px;
 display: block;
 margin: 10px auto;
 border: 0;
}
</style>
<p><img src="https://picsum.photos/id/5/1920/1080" /></p>
<p><img class="lazy" data-src="https://picsum.photos/id/15/1920/1080" /></p>
<p><img class="lazy" data-src="https://picsum.photos/id/25/1920/1080" /></p>
<p><img class="lazy" data-src="https://picsum.photos/id/35/1920/1080" /></p>
<p><img class="lazy" data-src="https://picsum.photos/id/55/1920/1080" /></p>
<script>
document.addEventListener("DOMContentLoaded", function() {
 var lazyloadImages = document.querySelectorAll("img.lazy");
 var lazyloadTimeout;
 function lazyload() {
  if(lazyloadTimeout) {
   clearTimeout(lazyloadTimeout);
  }
  lazyloadTimeout = setTimeout(function() {
   var scrollTop = window.pageYOffset;
   lazyloadImages.forEach(function(img) {
    if(img.offsetTop < (window.innerHeight + scrollTop)) {
     img.src = img.dataset.src;
     img.classList.remove('lazy');
    }
   });
   if(lazyloadImages.length == 0) {
    document.removeEventListener("scroll", lazyload);
    window.removeEventListener("resize", lazyload);
    window.removeEventListener("orientationChange", lazyload);
   }
  }, 50);
 }
 document.addEventListener("scroll", lazyload);
 window.addEventListener("resize", lazyload);
 window.addEventListener("orientationChange", lazyload);
});
</script>

 

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

 

 

Способ №2: Отложенная загрузка изображения с помощью API Intersection Observer

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

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

<style>
/* заполнитель для картинок */img {
 background: #ccc;
 width: 1920px;
 height: 1080px;
 display: block;
 margin: 10px auto;
 border: 0;
}
</style>
<p><img src="https://picsum.photos/id/5/1920/1080" /></p>
<p><img class="lazy" data-src="https://picsum.photos/id/15/1920/1080" /></p>
<p><img class="lazy" data-src="https://picsum.photos/id/25/1920/1080" /></p>
<p><img class="lazy" data-src="https://picsum.photos/id/35/1920/1080" /></p>
<p><img class="lazy" data-src="https://picsum.photos/id/55/1920/1080" /></p>
<script>
document.addEventListener("DOMContentLoaded", function() {
 var lazyloadImages;
 if ("IntersectionObserver" in window) {
  lazyloadImages = document.querySelectorAll(".lazy");
  var imageObserver = new IntersectionObserver(function(entries, observer) {
   entries.forEach(function(entry) {
    if (entry.isIntersecting) {
     var image = entry.target;
     image.src = image.dataset.src;
     image.classList.remove("lazy");
     imageObserver.unobserve(image);
    }
   });
  });
  lazyloadImages.forEach(function(image) {
   imageObserver.observe(image);
  });
 } else {
  var lazyloadTimeout;
  lazyloadImages = document.querySelectorAll(".lazy");
  function lazyload() {
   if(lazyloadTimeout) {
    clearTimeout(lazyloadTimeout);
   }
   lazyloadTimeout = setTimeout(function() {
    var scrollTop = window.pageYOffset;
    lazyloadImages.forEach(function(img) {
     if(img.offsetTop < (window.innerHeight + scrollTop)) {
      img.src = img.dataset.src;
      img.classList.remove('lazy');
     }
    });
    if(lazyloadImages.length == 0) {
     document.removeEventListener("scroll", lazyload);
     window.removeEventListener("resize", lazyload);
     window.removeEventListener("orientationChange", lazyload);
    }
   }, 50);
  }
  document.addEventListener("scroll", lazyload);
  window.addEventListener("resize", lazyload);
  window.addEventListener("orientationChange", lazyload);
 }
})
</script>

 

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

Важно! Учтите, что поддержка API Intersection Observer доступна не во всех браузерах.

 

 

Зависимость отложенной загрузки от JavaScript

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

 

 

Популярные JavaScript библиотеки для ленивой загрузки

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

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

(библиотеки представлены в алфавитном порядке)

  • BLazy.js
  • Echo.js
  • lazySizes
  • jQuery Lazy
  • jQuery Lazy Load XT
  • yall.js (Yet Another Lazy Loader)

 

 

 

Как протестировать отложенную загрузку?

После того, как вы внедрили отложенную загрузку, вы, вероятно, захотите убедиться, что она работает так, как задумано. Самый простой способ – открыть инструменты разработчика в вашем браузере (нажмите F5 или Ctrl+Shift+I).

Оттуда перейдите в Сеть > Изображения (Network > Images). Обновите страницу и вы должны увидеть только загруженные изображения в этом списке.

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

 

Статья по теме: Как сделать отложенную загрузку для HTML, iframe и встроенного видео

 

Подведение итогов

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

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

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

 

Share

Последние посты

Антуан де Сент-Экзюпери

Никогда не теряй терпения — это последний ключ, отпирающий двери Антуан де Сент-Экзюпери   Читать далее

28/03/2024

Сомерсет Моэм

Когда вы станете старше, вы поймете, что в мире можно хоть как-нибудь жить только при… Читать далее

27/03/2024

Михаил Грушевский

Все учатся своему родному языку, а наша беда такова, что нужно учить его больше, чем… Читать далее

26/03/2024

ТОП-5 надежных покерных обменников

Профессиональный покер – это многочисленные турниры и крупные суммы, что требует правильной настройки финансовых инструментов.… Читать далее

25/03/2024

Гай Юлий Цезарь

Все вокруг стремятся истребить врагов, но не объединиться с друзьями Гай Юлий Цезарь   Читать далее

24/03/2024

Как выбрать оптимальный смартфон для ребенка?

Сегодняшние дети сталкиваются с технологиями с самого раннего возраста, и смартфон уже давно перестал быть… Читать далее

22/03/2024