Оптимизация изображений для сайта: WebP, AVIF, srcset и lazy loading
Практика3 минРедакция Innovialabs
Коротко
Отдавайте WebP или AVIF, подбирайте размер под экран через srcset и sizes, ленитесь только ниже первого экрана, всегда указывайте width и height — и автоматизируйте это сборкой или image CDN.
Главное за минуту
Изображения часто составляют самую тяжёлую часть страницы и нередко являются LCP-элементом. Оптимизация сводится к четырём вещам:
- Правильный формат — WebP или AVIF вместо тяжёлых JPEG/PNG.
- Правильный размер — браузер скачивает картинку под ширину экрана, а не оригинал.
- Правильный момент загрузки — то, что ниже первого экрана, грузится позже.
- Зарезервированное место — чтобы страница не прыгала при загрузке.
Как выбрать формат
| Формат | Когда использовать | Нюансы |
|---|---|---|
| AVIF | Фото и сложные изображения, где важен минимальный вес | Кодирование медленнее; держите fallback |
| WebP | Универсальный выбор для фото и графики с прозрачностью | Широкая поддержка в современных браузерах |
| JPEG | Fallback для фото | Используйте progressive и разумное качество |
| PNG | Скриншоты с мелким текстом, когда нужна точность | Для фото обычно слишком тяжёлый |
| SVG | Иконки, логотипы, простые иллюстрации | Оптимизируйте через SVGO, не вставляйте растр внутрь |
Отдавать несколько форматов можно через <picture> — браузер возьмёт первый поддерживаемый:
<picture>
<source srcset="/img/hero.avif" type="image/avif">
<source srcset="/img/hero.webp" type="image/webp">
<img src="/img/hero.jpg" alt="Описание" width="1200" height="630">
</picture>
Сжатие
- Сжатие с потерями почти всегда допустимо для фото. Подбирайте качество на глаз на реальных примерах, а не одной цифрой для всего.
- Удаляйте метаданные (EXIF) — они бесполезны для страницы.
- Не храните в репозитории «сырые» снимки с камеры как готовые ресурсы — прогоняйте их через сборку или инструменты вроде Squoosh, sharp, imagemin.
Адаптивные изображения: srcset и sizes
srcset перечисляет варианты картинки разной ширины, sizes подсказывает браузеру, какую ширину изображение займёт на экране. Браузер сам выбирает подходящий файл с учётом плотности пикселей.
<img
src="/img/card-800.webp"
srcset="/img/card-400.webp 400w, /img/card-800.webp 800w, /img/card-1600.webp 1600w"
sizes="(max-width: 768px) 100vw, 33vw"
alt="Описание карточки"
width="800" height="600">
Частая ошибка — не указать sizes: тогда браузер считает, что картинка занимает всю ширину экрана, и скачивает самый большой вариант.
Lazy loading
- Атрибут
loading="lazy"откладывает загрузку изображений, пока они не приблизятся к видимой области. JavaScript для этого не нужен. - Не ставьте его на изображения первого экрана и особенно на LCP-картинку — это замедлит отрисовку.
- Для главного изображения, наоборот, можно добавить
fetchpriority="high". decoding="async"помогает не блокировать основной поток декодированием.
Размеры и CLS
Если у <img> нет width и height, браузер не знает пропорций, пока файл не загрузится, и контент ниже «прыгает». Это ухудшает метрику CLS.
- Всегда указывайте
widthиheight(реальные пропорции), а в CSS —height: autoдля адаптивности. - Для контейнеров с фоновыми изображениями используйте
aspect-ratio.
Image CDN и фреймворки
Вручную нарезать варианты для каждой картинки неудобно. Обычно это автоматизируют:
- Image CDN — сервис или свой прокси, который на лету меняет размер, формат и качество по параметрам URL и кэширует результат.
- Компоненты фреймворков — например,
next/imageв Next.js генерируетsrcset, отдаёт современные форматы и по умолчанию включает ленивую загрузку.
При выборе смотрите на: поддержку AVIF/WebP, автоматическое определение формата по заголовку Accept, кэширование и стоимость трафика.
Чек-лист
- Фото в WebP/AVIF с fallback.
-
srcset+ корректныйsizes. -
loading="lazy"только ниже первого экрана. -
width/heightилиaspect-ratioу всех изображений. - Осмысленный
altдля контентных картинок, пустойalt=""для декоративных. - Метаданные удалены, SVG оптимизированы.