Производительность изображения

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

Изображения можно добавить на страницу с помощью элементов <img> или <picture> , либо с помощью свойства CSS background-image .

размер изображения

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

Однако выбор оптимального размера изображения зависит от множества переменных, что делает задачу выбора подходящего размера изображения в каждом конкретном случае довольно сложной. В 2010 году, когда был выпущен iPhone 4, разрешение экрана (640x960) было вдвое больше, чем у iPhone 3 (320x480). Тем не менее, физический размер экрана iPhone 4 остался примерно таким же, как у iPhone 3.

Отображение всего в более высоком разрешении значительно уменьшило бы размер текста и изображений — ровно вдвое. Вместо этого 1 пиксель стал равен 2 пикселям устройства . Это называется коэффициентом пикселизации устройства (DPR) . У iPhone 4 (и многих моделей iPhone, выпущенных после него) DPR составлял 2.

Возвращаясь к предыдущему примеру, если устройство имеет DPR, равный 2, и изображение отображается в контейнере размером 500 на 500 пикселей, то оптимальным размером будет квадратное изображение размером 1000 пикселей (называемое внутренним размером ). Аналогично, если устройство имеет DPR, равный 3, то оптимальным размером будет квадратное изображение размером 1500 пикселей.

srcset

Элемент <img> поддерживает атрибут srcset , который позволяет указать список возможных источников изображений, которые может использовать браузер. Каждый указанный источник изображения должен включать URL изображения и описание ширины или плотности пикселей.

<img
  alt="An image"
  width="500"
  height="500"
  src="/image-500.jpg"
  srcset="/image-500.jpg 1x, /image-1000.jpg 2x, /image-1500.jpg 3x"
>

Приведенный выше HTML-фрагмент использует дескриптор плотности пикселей, чтобы указать браузеру использовать image-500.png на устройствах с DPR равным 1, image-1000.jpg на устройствах с DPR равным 2 и image-1500.jpg на устройствах с DPR равным 3.

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

sizes

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

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

<img
  alt="An image"
  width="500"
  height="500"
  src="/image-500.jpg"
  srcset="/image-500.jpg 500w, /image-1000.jpg 1000w, /image-1500.jpg 1500w"
  sizes="(min-width: 768px) 500px, 100vw"
>

В приведенном выше HTML-фрагменте атрибут srcset задает список вариантов изображений, из которых браузер может выбирать, разделенных запятыми. Каждый вариант в списке состоит из URL-адреса изображения, за которым следует синтаксис, обозначающий внутреннюю ширину изображения. Внутренний размер изображения — это его размеры. Например, дескриптор 1000w означает, что внутренняя ширина изображения составляет 1000 пикселей.

Используя эту информацию, браузер оценивает состояние медиафайлов в атрибуте sizes и — в данном случае — получает указание, что если ширина области просмотра устройства превышает 768 пикселей, изображение отображается шириной 500 пикселей. На устройствах меньшего размера изображение отображается шириной 100vw — или полной шириной области просмотра.

Затем браузер может объединить эту информацию со списком источников изображений srcset , чтобы найти оптимальное изображение. Например, если пользователь использует мобильное устройство с шириной экрана 320 пикселей и DPR равным 3, изображение отображается размером 320 CSS pixels x 3 DPR = 960 device pixels . В этом примере изображение ближайшим по размеру будет image-1000.jpg , имеющее внутреннюю ширину 1000 пикселей ( 1000w ).

Форматы файлов

Браузеры поддерживают несколько различных форматов графических файлов. Современные форматы изображений, такие как WebP и AVIF, могут обеспечивать лучшее сжатие, чем PNG или JPEG, что уменьшает размер файла изображения и, следовательно, сокращает время его загрузки. Использование современных форматов изображений позволяет сократить время загрузки ресурса , что может привести к снижению показателя Largest Contentful Paint (LCP) .

WebP — это широко распространенный формат, работающий во всех современных браузерах. WebP часто обеспечивает лучшее сжатие, чем JPEG, PNG или GIF, предлагая как сжатие с потерями , так и без потерь. WebP также поддерживает прозрачность альфа-канала даже при использовании сжатия с потерями — функция, которой нет у кодека JPEG.

AVIF — это более новый формат изображений, и хотя он не так широко распространен, как WebP, он имеет достаточно хорошую поддержку во всех браузерах . AVIF поддерживает как сжатие с потерями, так и без потерь, и тесты показали экономию более чем на 50% по сравнению с JPEG в некоторых случаях. AVIF также предлагает функции широкого цветового охвата (WCG) и расширенного динамического диапазона (HDR) .

Сжатие

Что касается изображений, существует два типа сжатия:

  1. Сжатие с потерями
  2. Сжатие без потерь

Сжатие с потерями работает за счет снижения точности изображения путем квантования , а дополнительная информация о цвете может быть отброшена с помощью субдискретизации хроматики . Сжатие с потерями наиболее эффективно для изображений с высокой плотностью, большим количеством шума и цветов — как правило, это фотографии или изображения с аналогичным содержимым. Это связано с тем, что артефакты, создаваемые сжатием с потерями, гораздо менее заметны на таких детализированных изображениях. Однако сжатие с потерями может быть менее эффективным для изображений, содержащих резкие края, таких как линейная графика, аналогичные резкие детали или текст. Сжатие с потерями может применяться к изображениям в форматах JPEG, WebP и AVIF.

Сжатие без потерь уменьшает размер файла за счет сжатия изображения без потери данных. Сжатие без потерь описывает пиксель на основе разницы с соседними пикселями. Сжатие без потерь используется для форматов изображений GIF, PNG, WebP и AVIF.

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

Элемент <picture>

Элемент <picture> предоставляет большую гибкость при указании нескольких вариантов изображений:

<picture>
  <source type="image/avif" srcset="image.avif">
  <source type="image/webp" srcset="image.webp">
  <img
    alt="An image"
    width="500"
    height="500"
    src="/image.jpg">
</picture>

При использовании элемента(ов) <source> внутри элемента <picture> можно добавить поддержку изображений AVIF и WebP, но в случае, если браузер не поддерживает современные форматы, он будет использовать более совместимые устаревшие форматы изображений. При таком подходе браузер выбирает первый указанный элемент <source> , который соответствует требованиям. Если он может отобразить изображение в этом формате, он использует это изображение. В противном случае браузер переходит к следующему указанному элементу <source> . В приведенном выше фрагменте HTML формат AVIF имеет приоритет над форматом WebP, и в случае, если ни AVIF, ни WebP не поддерживаются, используется формат JPEG.

Для элемента <picture> требуется вложенный в него элемент <img> . Атрибуты alt , width и height определены для элемента <img> и используются независимо от того, какой <source> выбран.

Элемент <source> также поддерживает атрибуты media , srcset и sizes . Аналогично примеру с <img> , приведенному ранее, они указывают браузеру, какое изображение следует выбрать при разных размерах окна просмотра.

<picture>
  <source
    media="(min-resolution: 1.5x)"
    srcset="/image-1000.jpg 1000w, /image-1500.jpg 1500w"
    sizes="(min-width: 768px) 500px, 100vw">
  <img
    alt="An image"
    width="500"
    height="500"
    src="/image-500.jpg">
</picture>

Атрибут media принимает условие `media` . В приведенном выше примере в качестве условия `media` используется значение `DPR` устройства. Любое устройство со значением `DPR` больше или равным 1,5 будет использовать первый элемент <source> . Элемент <source> сообщает браузеру, что на устройствах с шириной области просмотра более 768 пикселей выбранное изображение отображается шириной 500 пикселей. На устройствах меньшего размера это изображение занимает всю ширину области просмотра. Комбинируя атрибуты media и srcset , вы можете более точно контролировать, какое изображение использовать.

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

Ширина области просмотра (в пикселях) 1 ДПР 1,5 ДПР 2 ДПР 3 ДПР
320 500.jpg 500.jpg 500.jpg 1000.jpg
480 500.jpg 500.jpg 1000.jpg 1500.jpg
560 500.jpg 1000.jpg 1000.jpg 1500.jpg
1024 500.jpg 1000.jpg 1000.jpg 1500.jpg
1920 500.jpg 1000.jpg 1000.jpg 1500.jpg

Устройства с показателем DPR, равным 1, загружают image-500.jpg , включая большинство пользователей настольных компьютеров, которые просматривают изображение в размере 500 пикселей по ширине. С другой стороны, пользователи мобильных устройств с показателем DPR, равным 3, загружают потенциально большее image-1500.jpg — то же самое изображение, которое используется на настольных устройствах с показателем DPR, равным 3.

<picture>
  <source
    media="(min-width: 561px) and (min-resolution: 1.5x)"
    srcset="/image-1000.jpg 1000w, /image-1500.jpg 1500w"
    sizes="(min-width: 768px) 500px, 100vw">
  <source
    media="(max-width: 560px) and (min-resolution: 1.5x)"
    srcset="/image-1000-sm.jpg 1000w, /image-1500-sm.jpg 1500w"
    sizes="(min-width: 768px) 500px, 100vw">
  <img
    alt="An image"
    width="500"
    height="500"
    src="/image-500.jpg">
</picture>

В этом примере элемент <picture> был изменен таким образом, чтобы включить дополнительный элемент <source> для использования разных изображений на устройствах с широким экраном и высоким показателем DPR:

Ширина области просмотра (в пикселях) 1 ДПР 1,5 ДПР 2 ДПР 3 ДПР
320 500.jpg 500.jpg 1000-sm.jpg 1000-sm.jpg
480 500.jpg 500.jpg 1000-sm.jpg 1500-sm.jpg
560 500.jpg 1000-sm.jpg 1000-sm.jpg 1500-sm.jpg
1024 500.jpg 1000.jpg 1000.jpg 1500.jpg
1920 500.jpg 1000.jpg 1000.jpg 1500.jpg

С помощью этого дополнительного запроса вы можете увидеть, что image-1000-sm.jpg и image-1500-sm.jpg отображаются в небольших окнах просмотра. Эта дополнительная информация позволяет еще больше сжимать изображения, поскольку артефакты сжатия не так заметны при таком размере и плотности, при этом качество изображения не ухудшается на настольных устройствах.

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

<picture>
  <source
    media="(min-width: 561px)"
    srcset="/image-500.jpg, /image-1000.jpg 2x, /image-1500.jpg 3x">
  <source
    media="(max-width: 560px)"
    srcset="/image-500.jpg 1x, /image-1000.jpg 2x">
  <img
    alt="An image"
    width="500"
    height="500"
    src="/image-500.jpg">
</picture>

В приведенном выше HTML-фрагменте дескрипторы ширины были удалены в пользу дескрипторов коэффициента пикселизации устройства. Изображения, отображаемые на мобильном устройстве, ограничены форматами /image-500.jpg или /image-1000.jpg , даже на устройствах с коэффициентом пикселизации 3.

Управление сложностью

При работе с адаптивными изображениями вы можете столкнуться с множеством различных размеров и форматов для каждого изображения. В приведенном выше примере используются варианты для каждого размера, но исключаются форматы AVIF и WebP. Сколько вариантов должно быть? Как и во многих инженерных задачах, ответ обычно звучит так: «зависит от обстоятельств».

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

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

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

Отображать изображения на основе заголовка запроса Accept

Заголовок HTTP-запроса Accept сообщает серверу, какие типы контента понимает браузер пользователя. Эта информация может быть использована вашим сервером для предоставления изображения в оптимальном формате без добавления лишних байтов к вашим HTML-ответам.

if (request.headers.accept) {
  if (request.headers.accept.includes('image/avif')) {
    return reply.from('image.avif');
  } else if (request.headers.accept.includes('image/webp')) {
    return reply.from('image.webp');
  }
}

return reply.from('image.jpg');

Приведённый выше HTML-фрагмент представляет собой упрощённую версию кода, который вы можете добавить в JavaScript-бэкэнд вашего сервера, чтобы выбрать и отдать оптимальный формат изображения. Если заголовок Accept запроса содержит image/avif , то будет отдано изображение в формате AVIF. В противном случае, если заголовок Accept содержит image/webp , будет отдано изображение в формате WebP. Если ни одно из этих условий не выполняется, то будет отдано изображение в формате JPEG.

Практически на любом типе веб-сервера можно изменять ответы на основе содержимого заголовка Accept — например, на серверах Apache можно переписывать запросы изображений на основе заголовка Accept с помощью mod_rewrite .

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

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

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

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

Декодирование атрибута

Атрибут decoding указывает браузеру, как он должен декодировать изображение. Возможны три значения:

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

В JavaScript метод decode можно использовать для экземпляра элемента HTMLImageElement при вставке изображения в DOM.

Демонстрация изображения

Проверьте свои знания

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

GIF.
Правильный!
JPEG.
Попробуйте еще раз.
Папуа-Новая Гвинея.
Правильный!
ВебП.
Правильный!
АВИФ.
Правильный!

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

GIF.
Попробуйте еще раз. Хотя формат GIF поддерживает только ограниченную палитру из 256 цветов, кодирование с потерями необходимо выполнить перед преобразованием в GIF.
JPEG.
Правильный!
Папуа-Новая Гвинея.
Попробуйте еще раз.
ВебП.
Правильный!
АВИФ.
Правильный!

Что сообщает браузеру дескриптор ширины (например, 1000w ) о потенциальном изображении, указанном в атрибуте srcset ?

Внешняя ширина изображения — то есть размеры изображения в макете после применения стилей к странице.
Попробуйте еще раз.
Внутренняя ширина изображения — то есть, размеры самого изображения.
Правильный!

Что сообщает браузеру атрибут sizes о том, к какому элементу <img> он применяется?

Логика, определяющая, какой из вариантов, указанных в srcset элемента <img> , следует загрузить, учитывая размеры текущей области просмотра пользователя.
Правильный!
Внутренняя ширина изображения, загружаемого из атрибута srcset элемента <img> .
Попробуйте еще раз.

Далее: Видеовыступление

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