Предварительная загрузка адаптивных изображений
Начиная с Chrome 73 адаптивные изображения можно комбинировать с link rel="preload", чтобы ускорить их загрузку.
В этой статье я расскажу сразу про две своих любимых темы: адаптивные изображения и предварительную загрузку. Как человек, который участвовал в разработке обеих функций, я очень рад возможности использовать их вместе.
Краткий обзор адаптивных изображений #
Представьте, что вы просматриваете веб-страницу на экране шириной в 300 пикселей и она загружает изображение, имеющее ширину 1500 пикселей. Это приведет к чрезмерному расходу мобильного трафика, поскольку экран устройства не может отобразить изображение с таким разрешением. В идеале браузер должен загрузить версию изображения с шириной чуть больше ширины экрана, например 325 пикселей, чтобы обеспечить высокую четкость без избыточного расхода трафика. Кроме того, такое изображение будет быстрее загружаться. Адаптивные изображения позволяют браузеру загружать различные ресурсы в зависимости от параметров устройства. Если вы не используете CDN для доставки изображений, для каждого изображения необходимо сгенерировать версии разных размеров и указать их в атрибуте srcset
. Параметр w
сообщает браузеру ширину каждой версии. В зависимости от параметров устройства браузер выбирает наиболее подходящую версию:
<img src="small.jpg" srcset="small.jpg 500w, medium.jpg 1000w, large.jpg 1500w" alt="…">
Краткий обзор предварительной загрузки #
Механизм предварительной загрузки позволяет сообщать браузеру о критически важных ресурсах, которые необходимо загружать в первую очередь, еще до их обнаружения в HTML. Это особенно полезно для ресурсов, обнаружение которых занимает много времени, таких как шрифты в таблицах стилей, фоновые изображения, а также ресурсы, загружаемые из скриптов.
<link rel="preload" as="image" href="important.png">
Адаптивные изображения + предварительная загрузка = ускоренная загрузка изображений #
Адаптивные изображения и предварительная загрузка были доступны уже несколько лет, но в то же время чего-то не хватало: отсутствовала возможность использовать предварительную загрузку для адаптивных изображений. Начиная с Chrome 73 браузер может выполнять предварительную загрузку наиболее подходящего из изображений, указанных в атрибуте srcset
, еще до обнаружения тега img
.
В зависимости от структуры сайта это может значительно ускорить отображение изображений. Мы провели тесты на сайте, который использует JavaScript для отложенной загрузки адаптивных изображений. Благодаря предварительной загрузке изображения стали загружаться на 1,2 секунды быстрее.
imagesrcset
и imagesizes
#
Чтобы обеспечить поддержку предварительной загрузки адаптивных изображений, мы добавили новые атрибуты элемента <link>
: imagesrcset
и imagesizes
. Они используются в тегах <link rel="preload">
, и их синтаксис совпадает с атрибутами srcset
и sizes
тега <img>
.
Например, если необходимо обеспечить предварительную загрузку следующего адаптивного изображения:
<img src="wolf.jpg" srcset="wolf_400px.jpg 400w, wolf_800px.jpg 800w, wolf_1600px.jpg 1600w" sizes="50vw" alt="A rad wolf">
…вы можете добавить в раздел <head>
следующий HTML-код:
<link rel="preload" as="image" href="wolf.jpg" imagesrcset="wolf_400px.jpg 400w, wolf_800px.jpg 800w, wolf_1600px.jpg 1600w" imagesizes="50vw">
Это позволяет инициировать запрос с использованием логики выбора ресурсов, соответствующей значениям атрибутов srcset
и sizes
.
Сценарии использования #
Предварительная загрузка динамически подставляемых адаптивных изображений #
Предположим, что ваша страница динамически загружает hero-изображения для слайд-шоу и вам известно, какое изображение будет показано в первую очередь. В этом случае будет целесообразным загружать его сразу, не дожидаясь выполнения скрипта, чтобы пользователь увидел изображение как можно быстрее.
Эту проблему можно изучить на примере сайта с динамически загружаемой галереей изображений:
Откройте в новой вкладке сайт с примером.
Откройте DevTools, нажав
Control+Shift+J
(илиCommand+Option+J
, если у вас Mac).Перейдите на вкладку Сеть.
В раскрывающемся списке Ограничение выберите 3G (высокая скорость).
Снимите флажок Отключить кеш.
Обновите страницу.

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

Чтобы увидеть прирост, который дает предварительная загрузка, вы можете ознакомиться с аналогичной динамически загружаемой галереей изображений, но использующей предварительную загрузку первого изображения, выполнив шаги из первого примера.
Предварительная загрузка фоновых изображений при помощи image-set #
Если на вашей странице в зависимости от плотности пикселей экрана используются различные фоновые изображения, вы можете указать их в CSS, используя синтаксис image-set
. Тогда браузер сможет выбрать наиболее подходящее изображение исходя из DPR экрана.
background-image: image-set( "cat.png" 1x, "cat-2x.png" 2x);
Недостаток фоновых изображений, указываемых при помощи CSS, заключается в том, что браузер обнаруживает их только после загрузки и обработки всего содержащегося в разделе <head>
CSS-кода, которого может быть очень много.
Эту проблему можно изучить на примере сайта с адаптивным фоновым изображением.

Предварительная загрузка адаптивных изображений — это простой и изящный способ ускорить загрузку таких изображений.
<link rel=preload href=cat.png as=image imagesrcset="cat.png 1x, cat-2x.png 2x">
Вы можете изучить, как меняется поведение предыдущего примера при использовании предварительной загрузки адаптивного фонового изображения.

Предварительная загрузка адаптивных изображений в действии #
В теории предварительная загрузка адаптивных изображений может ускорить их отображение, но что происходит на практике?
Чтобы ответить на этот вопрос, я создал две копии демонстрационного PWA-приложения магазина; одна из копий не использует предварительную загрузку изображений, а другая использует ее для некоторых изображений. Поскольку на сайте применяется отложенная загрузка изображений при помощи JavaScript, его работу, вероятно, можно ускорить за счет предварительной загрузки изображений, расположенных в исходной области просмотра.
С результатами вы можете ознакомиться здесь (без предварительной загрузки) и здесь (с предзагрузкой изображений). Глядя на цифры, мы видим, что показатель Start Render («начало рендеринга») остался прежним, Speed Index («индекс скорости») слегка улучшился (273 мс, так как изображения загружаются быстрее, но занимают небольшую площадь от общего числа пикселей), но сильнее всего отражает разницу показатель Last Painted Hero («последнее отрисованное hero-изображение»), который улучшился на 1,2 секунды. 🎉🎉
Конечно, ничто не передает разницу так наглядно, как покадровая визуализация:

Предварительная загрузка и <picture>
#
Если вы знакомы с адаптивными изображениями, у вас может возникнуть вопрос: «А что насчет тега <picture>
?».
Рабочая группа Web Performance Working Group рассматривает возможность расширить поддержку предварительной загрузки на атрибуты srcset
и sizes
, но не на элемент <picture>
, который используется для так называемого «художественного преобразования» .
Почему этим сценарием использования пренебрегают?
Хотя данный сценарий использования также представляет интерес, существует ряд нерешенных технических проблем, значительно усложняющих реализацию возможного решения. Кроме того, данный сценарий, по всей видимости, решается существующими средствами, хотя и не очень изящным способом (см. ниже).
На основании этого рабочая группа Web Performance решила сначала реализовать поддержку предзагрузки для атрибута srcset
, а затем оценить спрос на аналогичную функциональность для элемента picture
.
Если вам все-таки понадобится предварительная загрузка элемента <picture>
, в качестве альтернативного решения вы можете использовать метод, описанный ниже.
Рассмотрим следующий пример:
<picture>
<source src="small_cat.jpg" media="(max-width: 400px)">
<source src="medium_cat.jpg" media="(max-width: 800px)">
<img src="huge_cat.jpg">
</picture>
Логика работы элемента <picture>
(или, если точнее, логика выбора источника изображения) такова: элементы <source>
обходятся по порядку, пока не будет найден первый элемент с подходящим значением атрибута media
. Именно этот элемент используется в качестве источника ресурса.
Механизм адаптивной предварительной загрузки не учитывает порядок элементов, и критерии необходимо указывать с учетом этого факта:
<link rel="preload" href="small_cat.jpg" as="image" media="(max-width: 400px)">
<link rel="preload" href="medium_cat.jpg" as="image" media="(min-width: 400.1px) and (max-width: 800px)">
<link rel="preload" href="large_cat.jpg" as="image" media="(min-width: 800.1px)">
Подведение итогов #
Механизм предварительной загрузки адаптивных изображений открывает захватывающие возможности для оптимизации, которая ранее требовала нестандартных решений. Он является важным новым инструментом в арсенале разработчика, заботящегося о скорости, и позволяет оперативно доставлять пользователям важные изображения именно тогда, когда это требуется.