Адаптивные изображения для чайников или как корректно использовать атрибут
srcset тега img
srcset тега img

В этой статье обсудим, как работают адаптивные изображения, почему браузер выбирает именно такую версию картинки, а не любую другую и как грамотно задать условия в sizes.
Почему картинки шириной 320px никому не нужны
Как браузер обрабатывает тег img с атрибутом srcset
Как атрибут sizes позволяет контролировать работу браузера
Как самостоятельно сформировать sizes
Адаптивные иллюстрации и SEO
- Индексация иллюстраций
- Кол-во иллюстраций в srcset
- Увеличение веса страницы
- Адаптивные иллюстрации в AMP

Можно сократить ширину иллюстрации и опубликовать ее в уменьшенном виде. Но тогда наше фото как пользователи, так и поисковые роботы увидят в сжатом качестве.
Cделаем умнее: нарежем иллюстрацию на несколько копий и предложим браузеру выбрать нужную.
<img srcset="dog-640.jpg 640w,
dog-920.jpg 920w,
dog-1280.jpg 1280w,
dog-1600.jpg 1600w"
src="dog.jpg" alt="Пёсик">
Многие статьи по адаптивным изображениям на SEO-ресурсах заканчиваются где-то на этом моменте. Кто-то еще про sizes коротко рассказывает, мол, разберетесь. Из-за этого ни оптимизаторы, ни верстальщики зачастую не понимают, что вообще у себя на сайте внедряют. Углубимся в теорию.

Век экранов, у которых число реальных и CSS-пикселей совпадает, давно кончился. Помните, когда-то Apple революционно вышла на рынок с ретина-дисплеями? Это когда pixel ratio — 2. На Samsung Galaxy S6 2015 года соотношение физических пикселей к CSS-пикселям 4! Большинство китайских смартфонов сегодня — это pixel ratio 2-3.
А значит, если у нас на мобилке картинка занимает 360px, нет смысла загружать иллюстрацию шириной меньше, чем 360×2=720px! А обладатель корейского флагмана был бы не против и все 1440px загрузить.
Далее браузер идет в массив srcset, где ищет подходящую картинку. Например, идеальной была бы ширина 1032px, но есть только 1200px и 960px. Браузер возьмет 1200px, так как это подходящее значение (обычно браузер берет первое изображение, которое больше размера выбранного слота).
На демо-странице #1 вы можете потестировать, как браузер выбирает иллюстрацию при изменении pixel ratio устройства. Ширина картинки равна 360px и не зависит от device-width.
Основная иллюстрация ушла в src, в srcset я указал копии шириной 360px, 720px, 1080px, 1920px. На атрибут sizes пока не обращайте внимания.
<img srcset="dog-360.jpg 360w,
dog-720.jpg 720w,
dog-1080.jpg 1080w,
dog-1920.jpg 1920w"
sizes="360px" src="dog.jpg" alt="Пёсик" >
Вместо дескриптора ширины (w) может использоваться дескриптор плотности пикселей (x), когда мы говорим браузеру, что вот эта картинка для обычных устройств, а эта — для ретина-дисплеев. Но встречаю я такое редко, так что вернемся к нашей иллюстрации на демо-странице.



Картинка по-прежнему занимает 360 CSS-пикселей, device pixel ratio по-прежнему 3, однако браузер почему-то грузит слишком большую картинку. Причина — в отсутствии атрибута sizes. Если он не заполнен, то по умолчанию используется значение 100vw. То есть браузер считает, что такая картинка занимает 100% device width.
Так как мы загружаем страницу с шириной экрана 1920px, браузер полагает, что и картинка с песиком занимает 1920px в ширину, а значит, надо скачивать самую большую иллюстрацию из массива srcset.
Теперь мы можем полностью описать алгоритм работы с отзывчивыми изображениями:
sizes="(max-width: 560px) 100vw, 560px"
Кстати, обратите внимание, что max-width — это именно меньше или равно. Некоторые верстальщики из-за этого совершают ошибку, когда описывают в sizes якорные значения, при которых состояние картинки уже изменилось.
В большинстве случаев достаточно последовательного использования max-width, но можно конструировать условия любой сложности.
При этом описывать состояние картинки при текущем медиа-запросе можно как с помощью CSS-пикселей (px), так и с помощью vw — доли области просмотра в %.
sizes="((min-width: 600px) and (max-width: 1004px)) 84vw, (min-width: 1005px) 60vw, 100vw"
В качестве значения при медиа-запросе можно использовать и более сложные материи, например calc. Ниже пример sizes с одного из сайтов. В нем полностью описывается состояние иллюстрации при изменении device-width: например, если ширина экрана 1024px, то иллюстрация занимает (100% viewport - 504px) = 520px. Для этого используется calc.
<img srcset="/640.jpg 640w,
/920.jpg 920w,
/1280.jpg 1280w,
/1600.jpg 1600w,
/1920.jpg 1920w"
sizes="(max-width: 360px) calc(100vw - 40px),
(max-width: 767px) calc(100vw - 60px),
(max-width: 1023px) calc(100vw - 208px),
(max-width: 1279px) calc(100vw - 504px),
(max-width: 1439px) calc(100vw - 640px),
640px"
src="original.jpg" alt="Текст альта" decoding="async" loading="lazy">
Строго говоря, степень детализации sizes зависит только от дотошности верстальщика — если у вас создается всего две копии изображения шириной 640px и 1200px, то проще будет в sizes описать не реальные состояния верстки, а условия, при которых мы приказываем браузеру брать либо первое фото, либо второе.
Но если по-другому никак, то вооружайтесь Chrome DevTools и скромными математическими познаниями — большего не понадобится. Для примера я вместе с вами сформирую sizes для популярного российского новостного сайта.
Наша задача — описать состояния основной иллюстрации в зависимости от ширины экрана пользователя. Сколько картинка занимает в верстке, если человек заходит с телефона? А если с планшета? И так далее.
Заходим в DevTools и выставляем начальное значение девайса: Responsive, 320px. Кликаем правой клавишей по иллюстрации, которая нас интересует, и выбираем пункт «Просмотреть код». В панели разработчика появится html-код, центрированный на нашем изображении. Наводим курсор на <img>, после чего браузер подсветит текущие размеры иллюстрации.

Но как долго действует эта зависимость? Проще всего это выяснить, растягивая ширину нашего виртуального девайса. Выясняется, что где-то в районе 536px поля вокруг картинки увеличиваются. Находим точное значение — это 540px. При ширине девайса 541px, картинка по-прежнему занимает 500px, а не 501px, как мы планировали.

(max-width: 540px) calc(100vw - 40px)
Далее видим, что с 540px до 640px размер иллюстрации не меняется, увеличиваются только боковые поля. Это наше следующее условие:
(max-width: 640px) 500px
Текущий sizes у нас выглядит так:
(max-width: 540px) calc(100vw - 40px),
(max-width: 640px) 500px
Получаем финальный sizes:
sizes="(max-width: 540px) calc(100vw - 40px),
(max-width: 640px) 500px,
590px"
Для примера обратимся к новостному сайту, на котором реализованы адаптивные иллюстрации. В src уходит картинка размером 1600x900px, в srcset, помимо прочего, указана ее копия 921x518px.
Теперь идем в Google и смотрим, какую версию проиндексировал робот. Оказывается — оригинальную.

Если верстаете что-то трудозатратное, например, лендинг или ключевую страницу вашего сайта, то стоит заморочиться максимально. Изучите все состояния картинки в верстке и сопоставьте эти данные с аудиторией сайта.
Например, в Яндекс.Метрике можно выяснить, что 41% визитов на сайт происходит с девайсов шириной 360 CSS-пикселей. Обычно это всякие Samsung.

Если подробно изучать аудиторию нет времени, воспользуйтесь стандартными пропорциями, которые рекомендовал в докладе об изображениях Demi Murych:
Чтобы прощупать самостоятельно, поиграйтесь с тестовой страницей #4. Там две картинки: первая шириной 945px, вторая — с несколькими копиями в srcset.
Если пользователь заходит с дешевого китайского смартфона (360px device-width, pixel ratio 2), то загрузится версия на 640px. В нашем случае 277 килобайтов против 498 — экономия 44%.


Например, у нас есть статья с основной картинкой, которую пользователь загружает на первом экране. Для улучшения LCP нам выгодно, чтобы эта иллюстрация отрисовывалась как можно быстрее. Поэтому для нее мы прописываем srcset, в котором максимальное качество — x2. А остальные иллюстрации в статье — вплоть до x4, если так нужно.
Таким образом браузер загружает суперлегкую заглушку для иллюстраций, не попавших в поле зрения пользователя. Это позволяет ликвидировать недостаток адаптивных иллюстраций, связанный с увеличением общего объема картинок для пользователей с хорошими смартфонами.
И никаких проблем с индексацией: поисковый робот в srcset не заглядывает, используя лишь изображение максимального качества в src. Если заинтересовались, изучите соответствующее видео.
Полезные источники: MDN, Google Developers, WHATWG, Web.Dev.
Serpstat — набор инструментов для поискового маркетинга!
Находите ключевые фразы и площадки для обратных ссылок, анализируйте SEO-стратегии конкурентов, ежедневно отслеживайте позиции в выдаче, исправляйте SEO-ошибки и управляйте SEO-командами.
Набор инструментов для экономии времени на выполнение SEO-задач.
Используйте лучшие SEO инструменты
Проверка обратных ссылок
Быстрая проверка обратных ссылок вашего сайта и конкурентов
API для SEO
Получите быстро большие объемы данных используя SЕО API
Анализ конкурентов
Сделайте полный анализ сайтов конкурентов для SEO и PPC
Мониторинг позиций
Отслеживайте изменение ранжирования запросов используя мониторинг позиций ключей
Кейсы, лайфхаки, исследования и полезные статьи
Не успеваешь следить за новостями? Не беда! Наш любимый редактор подберет материалы, которые точно помогут в работе. Только полезные статьи, реальные кейсы и новости Serpstat раз в неделю. Присоединяйся к уютному комьюнити :)
Нажимая кнопку, ты соглашаешься с нашей политикой конфиденциальности.