- PVSM.RU - https://www.pvsm.ru -

Приемы оптимизации веб-графики в 2021 году

Привет!

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

Мотивация

Основной мотивацией к оптимизации, как и ранее, являются:

  • Уменьшение нагрузки на интернет-канал.

  • Уменьшение потребления CPU при отрисовке изображений.

Также давайте вспомним, что у нас есть метрики Google’s Core Web Vitals (LCP [1], CLS [2], FID [3]), на их значения существенно влияет оптимизация работы с изображениями.

Ленивая загрузка

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

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

С помощью атрибута loading [4] элемента img можно указать браузеру на необходимость отложить загрузку изображений до тех пор, пока пользователь не дойдет до этапа взаимодействия с этим изображением, например, до пролистывания страницы.

<img src="..." loading="lazy" />

Сегодня атрибут loading поддерживается не всеми браузерами. Поэтому технику ленивой загрузки можно реализовать также с помощью data-атрибутов и JavaScript.

Ленивая отрисовка

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

При ленивой отрисовке для элементов, которые не попадают во viewport, браузер пропустит этапы Layout и Paint, что позволит сократить time to interactive (TTI [5]).

Прием относительно свежий, так как возник благодаря добавлению в CSS нового свойства — content-visibility [6]. При значении auto свойство информирует браузер о том, что позиционирование изображения в макете можно отложить до тех пор, пока оно не приблизится к отображаемой пользователю области. И по мере того, как пользователь будет листать страницу сайта, браузер будет определять, насколько изображение приближается к viewport. При достижении определенного расстояния DOM-элементы будут отрисованы, после чего будет загружено изображение.

<style>
  img {
    content-visibility: auto;
  }
</style>

Асинхронное декодирование

Рассмотрим такой пример:

<p>какой-то вступительный текст</p>
<img src="very-big.jpg" />
<p>очень важный для пользователя текст</p>

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

Чтобы избежать такой ситуации, можно использовать атрибут decoding [7] co значением async. Это позволит браузеру декодировать изображение вне основного потока, избегая нагрузки на процессор и не блокируя дальнейшую отрисовку DOM-элементов. То есть процесс декодирования изображения будет отложен на будущее, а браузер в свою очередь сможет отрисовать всё содержимое, не дожидаясь загрузки изображения.

<p>какой-то вступительный текст</p>
<img src="very-big.jpg" decoding="async" />
<p>очень важный для пользователя текст</p>

Резервирование вертикального пространства

Не так давно браузеры в последних своих версиях научились заранее резервировать в макете пространство для загружаемого изображения, тем самым предотвращая возможный сдвиг макета (CLS [2]). Чтобы браузер смог зарезервировать место под загружаемое изображение, необходимо задать его атрибуты ширины и высоты.

<style>
    img {
        max-width: 100%;
    		height: auto;
    }
</style>

<img width="1280" height="800" src="..."/>

Или, в качестве альтернативы, для резервирования вертикального пространства можно воспользоваться свойством aspect-ratio [8].

Адаптивность (srcset и sizes)

С помощью атрибутов srcset [9] и sizes [10] можно указать несколько вариантов одного изображения. Браузер рассчитает и выберет для загрузки тот вариант, который обеспечивает наилучшее соотношение размера и качества изображения для устройства пользователя.

<img 
   src="picture.jpg" 
   srcset=" 
      small.jpg 240w, 
      medium.jpg 300w, 
      large.jpg 720w
   " 
   sizes="(min-width: 960px) 720px, 100vw"
/>

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

Blurry placeholder

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

Пример Blurry placeholder.
Пример Blurry placeholder.

Одной из рекомендаций по созданию blurry placeholder является использование SVG-изображения в формате data-uri. Это намного практичнее, чем CSS-фильтры для создания эффекта размытия, потому что в данном случае он реализован на уровне самого SVG-файла. В результате это позволяет повысить производительность интерфейса и снизить нагрузку на процессор.

<style>
    img {
        background: cover url('data:image/svg+xml;charset=utf-8,...');
    }
</style>

<img src="..." />

Заключение

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

Автор: Slavent

Источник [11]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/interfejsy/368324

Ссылки в тексте:

[1] LCP: https://web.dev/i18n/ru/lcp/

[2] CLS: https://web.dev/cls/

[3] FID: https://web.dev/fid/

[4] loading: https://developer.mozilla.org/ru/docs/Web/HTML/Element/img#attr-loading

[5] TTI: https://web.dev/interactive/

[6] content-visibility: https://developer.mozilla.org/en-US/docs/Web/CSS/content-visibility

[7] decoding: https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/decoding

[8] aspect-ratio: https://css-tricks.com/aspect-ratio-boxes/

[9] srcset: https://developer.mozilla.org/ru/docs/Web/API/HTMLImageElement/srcset

[10] sizes: http://htmlbook.ru/html/link/sizes

[11] Источник: https://habr.com/ru/post/580850/?utm_source=habrahabr&utm_medium=rss&utm_campaign=580850