Клавиша / esc

Ленивая загрузка картинок с цветным превью

Как добавить цветное превью при ленивой загрузке изображения.

Время чтения: меньше 5 мин

Задача

Скопировано

Ленивая загрузка (lazy loadnig) — это асинхронная загрузка картинок на веб-странице. Это означает, что картинки загружаются после полной загрузки страницы или когда они появляются в видимой части окна браузера. Следовательно, если пользователь не будет прокручивать экран, то изображения, размещённые за пределами экрана, не будут загружаться.

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

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

При большом количестве изображений на сайте можно настроить приоритет их загрузки. Для этого можно использовать атрибут fetch-priority в теге <img>. Всего у атрибута есть 3 значения:

  1. high – высокий приоритет относительно других изображений.
  2. low – низкий приоритет относительно других изображений.
  3. auto – приоритет по умолчанию, который указывает на отсутствие предпочтения приоритета выборки. В таком случае браузер сам решает, что лучше для пользователя.

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

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

  1. Атрибут loading в теге <img>.
  2. Intersection Observer API.
  3. Использовать прогрессивные изображения.

Прогрессивные изображения (progressive images) – метод, позволяющий постепенно загружать изображения, начиная с низкого разрешения и улучшая его качество постепенно.

Ниже разберём решение с использованием progressive images.

Готовое решение

Скопировано
Открыть демо в новой вкладке

Разбор решения

Скопировано

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

Разметка

Скопировано
        
          
          <img  src="low-resolution.jpg"  data-src="high-resolution.jpg"  alt="Лягушка"  class="lazy-image"  id="progressive-image">
          <img
  src="low-resolution.jpg"
  data-src="high-resolution.jpg"
  alt="Лягушка"
  class="lazy-image"
  id="progressive-image"
>

        
        
          
        
      

Стили

Скопировано

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

Для блюра изображения в низком качестве добавлено свойство filter.

        
          
          .lazy-image {  width: 300px;  height: 250px;  background-repeat: no-repeat;  background-size: cover;  filter: blur(20px);}
          .lazy-image {
  width: 300px;
  height: 250px;
  background-repeat: no-repeat;
  background-size: cover;
  filter: blur(20px);
}

        
        
          
        
      

Скрипт

Скопировано

Код на JavaScript ожидает события DOMContentLoaded, чтобы убедиться, что весь DOM уже готов к обработке. Затем создаётся объект Image для загрузки изображения низкого разрешения (lowResImage). Когда это изображение загружено, мы изменяем атрибут src основного изображения (progressiveImage) на ссылку на полное изображение, которое будет загружено вместо низкого разрешения и убираем блюр.

        
          
          document.addEventListener('DOMContentLoaded', function() {  const progressiveImage = document.getElementById('progressive-image')  const lowResImage = new Image()  lowResImage.src = progressiveImage.src  lowResImage.onload = function() {    progressiveImage.src = progressiveImage.getAttribute('data-src')    progressiveImage.style.filter = 'none'  }})
          document.addEventListener('DOMContentLoaded', function() {
  const progressiveImage = document.getElementById('progressive-image')

  const lowResImage = new Image()
  lowResImage.src = progressiveImage.src
  lowResImage.onload = function() {
    progressiveImage.src = progressiveImage.getAttribute('data-src')
    progressiveImage.style.filter = 'none'
  }
})