Изображения часто являются самым тяжелым и наиболее распространенным ресурсом в Интернете. В результате оптимизация изображений может значительно повысить производительность вашего веб-сайта. В большинстве случаев оптимизация изображений означает сокращение времени работы сети за счет отправки меньшего количества байтов, но вы также можете оптимизировать количество байтов, отправляемых пользователю, предоставляя изображения, размер которых соответствует размеру устройства пользователя.
Изображения можно добавлять на страницу с помощью элементов <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 также предлагает функции Wide Color Gamut (WCG) и High Dynamic Range (HDR) .
Сжатие
Что касается изображений, существует два типа сжатия:
Сжатие с потерями работает за счет снижения точности изображения посредством квантования , а дополнительная цветовая информация может быть отброшена с помощью цветовой субдискретизации . Сжатие с потерями наиболее эффективно для изображений высокой плотности с большим количеством шума и цветов — обычно фотографий или изображений со схожим содержимым. Это связано с тем, что артефакты, создаваемые сжатием с потерями, гораздо менее вероятно будут замечены на таких подробных изображениях. Однако сжатие с потерями может быть менее эффективным для изображений, содержащих резкие края, таких как штриховая графика, аналогичные резкие детали или текст. Сжатие с потерями может применяться к изображениям 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, возвращаясь к формату JPEG, если ни AVIF, ни WebP не поддерживаются.
Элемент <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 condition . В предыдущем примере в качестве media condition используется 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-см.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 |
С помощью этого дополнительного запроса вы можете увидеть, что 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
, даже на устройствах с DPR 3.
Как управлять сложностью
При работе с адаптивными изображениями вы можете обнаружить, что у вас есть много различных вариантов размеров и форматов для каждого изображения. В предыдущем примере используются варианты для каждого размера, но исключаются AVIF и WebP. Сколько вариантов у вас должно быть? Как и во многих инженерных задачах, ответ, как правило, «зависит от обстоятельств».
Хотя может возникнуть соблазн иметь как можно больше вариантов для достижения наилучшего соответствия, каждый дополнительный вариант изображения имеет свою цену и менее эффективно использует кэш браузера. При наличии только одного варианта каждый пользователь получает одно и то же изображение, поэтому его можно кэшировать очень эффективно.
С другой стороны, если существует много вариаций, каждый вариант требует еще одну запись в кэше. Затраты на сервер могут увеличиться и производительность может ухудшиться, если запись в кэше варианта истекла, и изображение необходимо снова загрузить с исходного сервера.
Кроме того, размер вашего HTML-документа растет с каждым изменением. Вы можете обнаружить, что отправляете несколько килобайт HTML для каждого изображения.
Подавать изображения на основе заголовка запроса Accept
Заголовок запроса Accept
HTTP сообщает серверу, какие типы контента понимает браузер пользователя. Эта информация может использоваться вашим сервером для обслуживания оптимального формата изображения без добавления дополнительных байтов в ваши 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) . Сети доставки контента изображений являются отличными решениями для оптимизации изображений и отправки оптимального формата в зависимости от устройства и браузера пользователя.
Ключ в том, чтобы найти баланс, сгенерировать разумное количество кандидатов на изображения и измерить влияние на пользовательский опыт. Разные изображения могут давать разные результаты, а оптимизация, применяемая к каждому изображению, зависит от его размера на странице и устройств, которые используют ваши пользователи. Например, для главного изображения во всю ширину может потребоваться больше вариантов, чем для миниатюрных изображений на странице со списком товаров в электронной коммерции.
Ленивая загрузка
Можно указать браузеру лениво загружать изображения, когда они появляются в области просмотра, используя атрибут loading
. Значение атрибута lazy
указывает браузеру не загружать изображение, пока оно не окажется в области просмотра (или около нее). Это экономит пропускную способность, позволяя браузеру расставлять приоритеты в ресурсах, необходимых для отображения критического контента, который уже находится в области просмотра.
decoding
Атрибут decoding
сообщает браузеру, как он должен декодировать изображение. Значение async
сообщает браузеру, что изображение может быть декодировано асинхронно, что может сократить время рендеринга другого контента. Значение sync
сообщает браузеру, что изображение должно быть представлено одновременно с другим контентом. Значение по умолчанию auto
позволяет браузеру решать, что лучше для пользователя.
Демонстрационные изображения
Проверьте свои знания
Какие форматы изображений поддерживают сжатие без потерь ?
Какие форматы изображений поддерживают сжатие с потерями ?
Что дескриптор ширины (например, 1000w
) сообщает браузеру о кандидате на изображение, указанном в атрибуте srcset
?
Что атрибут sizes
сообщает браузеру об элементе <img>
, к которому он применен?
srcset
элемента <img>
.srcset
элемента <img>
, должен быть загружен, учитывая размеры текущего окна просмотра пользователя.Далее: Видео производительность
Хотя изображения могут быть наиболее распространенным типом медиа, используемым в Интернете, они далеко не единственный, который вам нужно иметь в виду, когда дело касается производительности. Видео — еще один распространенный тип медиа, используемый в Интернете, и у него есть свои соображения по производительности. В следующем модуле этого курса изучите некоторые методы оптимизации видео и способы их эффективной загрузки.