Представьте: ваш пользователь сидит в кофейне и отчаянно пытается загрузить ваш сайт на телефоне через нестабильный Wi-Fi, а главная страница решает показать ему изображение размером 5 МБ, которое изначально было разработано для 32-дюймового монитора 4K. Он ждёт. И ждёт. И в итоге уходит, переходя к конкурентам. Звучит знакомо? Добро пожаловать в удивительный мир неоптимизированных изображений — где благие намерения сталкиваются с ужасными показателями производительности.

Изображения — это тяжеловесы веб-контента, на которые обычно приходится 60–70% общего размера веб-страницы. Они также являются главными виновниками низких показателей Largest Contentful Paint и могут серьёзно повлиять на Cumulative Layout Shift, если с ними неправильно обращаться. Но вот хорошая новость: с правильными методами адаптивных изображений вы можете предоставлять идеальные по пикселям визуальные элементы, которые загружаются быстрее, чем ваши пользователи успеют сказать «адаптивный веб-дизайн».

Проблема производительности, о которой никто не говорит

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

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

graph TD A[Пользователь заходит на сайт] --> B{Определение размера экрана} B -->|Мобильный| C[Подача оптимизированного изображения для мобильного] B -->|Планшет| D[Подача изображения среднего размера] B -->|Настольный| E[Подача изображения в полном разрешении] C --> F[Быстрая загрузка + Отличный UX] D --> F E --> F F --> G[Лучшие показатели Core Web Vitals] G --> H[Улучшенное ранжирование в SEO]

Супергерой srcset: ваш новый лучший друг

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

Вот как правильно его реализовать:

<img
  src="fallback-image-800w.jpg"
  alt="Потрясающий пейзаж, который не убьет вашу пропускную способность"
  width="800"
  height="600"
  loading="lazy"
  decoding="async"
  srcset="
    landscape-400w.jpg 400w,
    landscape-800w.jpg 800w,
    landscape-1200w.jpg 1200w,
    landscape-1600w.jpg 1600w,
    landscape-2400w.jpg 2400w
  "
  sizes="
    (max-width: 480px) 100vw,
    (max-width: 768px) 90vw,
    (max-width: 1024px) 70vw,
    50vw
  "
>

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

Атрибут sizes: обучение браузеров думать

Атрибут sizes — это где вы можете поиграть в предсказателя, предсказывая, какого размера будет отображаться ваше изображение при разных размерах области просмотра. По сути, вы даёте браузеру дорожную карту ваших намерений по адаптивному дизайну.

Подход с ориентацией на мобильные устройства

Для дизайнов с ориентацией на мобильные устройства, запросы max-width работают интуитивно:

<img
  src="hero-fallback.jpg"
  srcset="
    hero-320w.jpg 320w,
    hero-640w.jpg 640w,
    hero-960w.jpg 960w,
    hero-1280w.jpg 1280w,
    hero-1920w.jpg 1920w
  "
  sizes="
    (max-width: 320px) 100vw,
    (max-width: 768px) 90vw,
    (max-width: 1024px) 70vw,
    50vw
  "
  alt="Изображение героя, которое загружается до того, как ваш кофе остынет"
>

Подход с ориентацией на настольные компьютеры

Если вы работаете с дизайном, ориентированным на настольные компьютеры, запросы min-width могут показаться более естественными:

<img
  src="content-image-fallback.jpg"
  srcset="
    content-320w.jpg 320w,
    content-640w.jpg 640w,
    content-960w.jpg 960w,
    content-1280w.jpg 1280w
  "
  sizes="
    (min-width: 1024px) 50vw,
    (min-width: 768px) 70vw,
    (min-width: 480px) 90vw,
    100vw
  "
  alt="Контентное изображение, оптимизированное для всех мыслимых размеров экрана"
>

Элемент Picture: когда srcset недостаточно

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

<picture>
  <source
    media="(max-width: 768px)"
    srcset="
      mobile-portrait-400w.jpg 400w,
      mobile-portrait-600w.jpg 600w
    "
    sizes="100vw"
  >
  <source
    media="(max-width: 1024px)"
    srcset="
      tablet-landscape-800w.jpg 800w,
      tablet-landscape-1200w.jpg 1200w
    "
    sizes="90vw"
  >
  <source
    srcset="
      desktop-wide-1200w.jpg 1200w,
      desktop-wide-1800w.jpg 1800w,
      desktop-wide-2400w.jpg 2400w
    "
    sizes="80vw"
  >
  <img
    src="fallback-800w.jpg"
    alt="Художественное направление в лучшем виде — разные кад
ры для разных устройств"
    width="800"
    height="600"
    loading="lazy"
  >
</picture>

Современные форматы изображений: игры-преобразователи производительности

Здесь всё становится интереснее. Хотя JPEG и PNG были надежными рабочими лошадками веба на протяжении десятилетий, современные форматы, такие как WebP и AVIF, могут уменьшить размер файлов на 25–50%, сохраняя при этом то же визуальное качество.

<picture>
  <source
    srcset="
      modern-image-400w.avif 400w,
      modern-image-800w.avif 800w,
      modern-image-1200w.avif 1200w
    "
    sizes="(max-width: 768px) 100vw, 50vw"
    type="image/avif"
  >
  <source
    srcset="
      modern-image-400w.webp 400w,
      modern-image-800w.webp 800w,
      modern-image-1200w.webp 1200w
    "
    sizes="(max-width: 768px) 100vw, 50vw"
    type="image/webp"
  >
  <img
    src="fallback-image-800w.jpg"
    src