Оптимизация изображений: WebP, AVIF, srcset
Почему важно
Что тормозит:
- Изображения — 60–80% трафика.
- 1 МБ картинка на мобильном = 3 сек.
- LCP — чаще всего картинка.
- Трафик CDN — деньги.
Что даёт оптимизация:
- LCP ↓ в 2–3×.
- Трафик ↓ в 3–5×.
- UX лучше.
- SEO лучше.
Правило: изображения — первое, что оптимизируют.
Форматы
JPEG:
- Фото без прозрачности.
- Устаревает.
PNG:
- Прозрачность.
- Скриншоты.
- Тяжёлый.
WebP:
- Современный.
- На 25–35% меньше.
- Поддержка 95%+.
AVIF:
- Ещё меньше на 20–30%.
- Поддержка 80%+.
- Кодирование медленнее.
SVG:
- Иконки, лого.
- Вектор.
GIF:
- Устарел, заменять на MP4/WebM.
Правило: JPEG / PNG → WebP + AVIF.
Что выбрать
| Тип | Формат |
|---|---|
| Фото | AVIF + WebP + JPEG |
| Лого | SVG |
| Иконки | SVG |
| Скриншоты | WebP / AVIF |
| Анимация | MP4 / WebM |
| Прозрачность | WebP / AVIF |
Правило: нет одного формата для всего.
<picture>
<picture>
<source srcset="img.avif" type="image/avif">
<source srcset="img.webp" type="image/webp">
<img src="img.jpg" alt="..." width="800" height="600" loading="lazy">
</picture>
Что делает: браузер выбирает лучший формат.
Правило: AVIF → WebP → JPEG.
srcset
<img
src="img-800.jpg"
srcset="
img-400.jpg 400w,
img-800.jpg 800w,
img-1200.jpg 1200w,
img-1600.jpg 1600w
"
sizes="
(max-width: 600px) 100vw,
(max-width: 1024px) 50vw,
800px
"
alt="..."
width="800"
height="600"
loading="lazy"
>
Что делает: выбирает подходящий размер.
Правило: srcset + sizes — обязательно.
sizes — что означает
sizes="
(max-width: 600px) 100vw, # на мобильном — весь экран
(max-width: 1024px) 50vw, # на планшете — половина
800px # на десктопе — 800px
"
Что даёт: браузер знает, какой размер подходит.
Правило: sizes — точно по CSS.
Возможные размеры
Правило:
- 400w — мобильные.
- 800w — планшеты.
- 1200w — десктоп.
- 1600w — retina десктоп.
- 2400w — retina 4K.
Правило: 3–5 вариантов достаточно.
DPR (retina)
<img
src="img@1x.jpg"
srcset="img@1x.jpg 1x, img@2x.jpg 2x, img@3x.jpg 3x"
alt="..."
>
Что даёт: retina получает @2x/@3x.
Правило: srcset по DPR — для иконок.
width и height
Обязательно:
<img src="img.jpg" width="800" height="600" alt="...">
Что даёт: нет CLS.
Правило: всегда width/height.
aspect-ratio
.image {
aspect-ratio: 16 / 9;
width: 100%;
object-fit: cover;
}
Что даёт: гибкий резерв.
object-fit
img {
object-fit: cover; /* обрезать */
object-fit: contain; /* вписать */
}
Правило: cover — для карточек, contain — для логотипов.
Preload LCP
<link
rel="preload"
as="image"
href="hero.avif"
imagesrcset="hero-400.avif 400w, hero-800.avif 800w"
imagesizes="100vw"
fetchpriority="high"
>
Что даёт: LCP-картинка грузится сразу.
Правило: preload + fetchpriority для LCP.
Оптимизация в сборке
Vite:
npm install -D vite-imagetools
import hero from './hero.jpg?w=1200&format=avif';
Next.js: автоматически через next/image.
Nuxt: @nuxt/image.
Правило: оптимизация — в сборке, не вручную.
CLI оптимизация
cwebp:
cwebp -q 80 input.jpg -o output.webp
avifenc:
avifenc -q 60 input.jpg output.avif
sharp-cli:
npx sharp-cli -i input.jpg -o output.avif
Правило: для существующих картинок — batch через CLI.
CDN
Cloudflare Images:
https://cdn.example.com/image.jpg?w=800&format=auto&quality=80
imgix:
https://example.imgix.net/image.jpg?w=800&fm=webp&q=80
Cloudinary:
https://res.cloudinary.com/xxx/image/upload/w_800,f_auto,q_auto/image.jpg
Что даёт:
- Оптимизация на лету.
- Формат авто.
- Размеры по URL.
- Кэш на CDN.
Правило: для больших — CDN Images.
Правило 100 KB
Ориентиры:
- Hero — до 200 KB.
- Карточка — до 100 KB.
- Аватар — до 30 KB.
- Иконка — до 5 KB.
Правило: больше — оптимизировать.
Что НЕ делать
- PNG для фото.
- GIF для видео.
- BMP / TIFF в проде.
- JPEG для иконок — SVG.
- Одну картинку для всех размеров.
Проверка
Что смотреть:
- PageSpeed — размер изображений.
- DevTools → Network — сортировка по размеру.
- Coverage — загружено vs нужно.
- Lighthouse — рекомендации.
Правило: топ-10 крупных — первыми.
Практика
1. Найдите топ-10 больших картинок.
2. Конвертируйте в WebP/AVIF.
3. Добавьте <picture> с fallback.
4. Настройте srcset + sizes.
5. LCP — preload + fetchpriority.
6. Включите CDN Images.
7. width/height — везде.
8. Замерьте LCP до/после.
9. Проверьте CLS.
10. Настройте авто-оптимизацию.
Частые ошибки
1. PNG для фото:
3× размер
Решение: WebP / AVIF.
2. Одна картинка для всех:
1600px на мобильном
Решение: srcset.
3. Без размеров:
CLS
Решение: width/height.
4. GIF для анимации:
10 MB
Решение: MP4.
5. Без preload LCP:
LCP медленный
Решение: preload.
6. Retina без @2x:
Мыльно
Решение: srcset по DPR.
7. Всё вручную:
Забывают
Решение: авто в сборке.
8. Без CDN:
Оригинал в проде
Решение: CDN.
Итог
- WebP + AVIF — стандарт.
<picture>— fallback.srcset+sizes— адаптив.- LCP — preload + fetchpriority.
- width/height — против CLS.
- SVG — для иконок.
- MP4 — вместо GIF.
- CDN — для больших.
- Авто — в сборке.
- 100 KB — ориентир.
Дальше — шрифты: preload, font-display.