Оптимизация изображений
Формат, размер, сжатие, lazy и priority, резервирование места и next/image.
Обновлено
Почему изображения так важны
На большинстве сайтов изображения составляют больше половины веса страницы и обычно являются элементом LCP (самым большим видимым элементом). Одна фотография на 4 МБ прямо с телефона может сделать страницу медленной, как бы хорошо ни был написан остальной код.
Оптимизация изображений — это 5 решений: формат, размер, сжатие, когда загружать и как зарезервировать место.
1. Правильный формат
| Формат | Для чего | Размер относительно JPEG |
|---|---|---|
| AVIF | фотографии, сложные изображения | ~на 50% меньше |
| WebP | фото, иллюстрации, прозрачность | ~на 25–35% меньше |
| JPEG | фотографии (универсальный запасной) | эталон |
| PNG | скриншоты с текстом, точная прозрачность | намного больше для фото |
| SVG | логотипы, иконки, векторные иллюстрации | крошечный, масштабируется бесконечно |
| GIF | — | нет — видео MP4 / WebM в 5–10 раз меньше |
2. Правильный размер
Не отдавайте картинку на 3000px в карточку шириной 300px. Правило: ширина изображения = отображаемая ширина × плотность экрана (обычно 2×). С srcset + sizes (см. Изображения и медиа) браузер сам выберет нужный вариант.
3. Сжатие
Качество 75–85 обычно визуально не отличить от 100, а весит вдвое меньше. Для SVG запускайте SVGO (удаляет метаданные, упрощает пути).
4. Когда загружать
| Изображение | Что делать |
|---|---|
| главное, видно сразу (LCP) | не lazy; fetchpriority="high" / priority в next/image |
| ниже первого экрана | loading="lazy" — загрузится, только когда приблизится |
| декоративные фоны | CSS, можно меньше / размытее |
5. Зарезервируйте место
width + height (или aspect-ratio в CSS) → браузер резервирует место до загрузки картинки → нет CLS.
next/image — всё сразу и автоматически
import Image from 'next/image'
import hero from '@/shared/assets/hero.jpg' // статический импорт: размеры + blur автоматически
<Image src={hero} alt="Команда в офисе" priority placeholder="blur" sizes="100vw" />
<Image
src={product.imageUrl} // удалённое изображение
alt={product.name}
width={600}
height={600}
sizes="(min-width: 64rem) 33vw, 100vw"
/>Что делает next/image |
Как |
|---|---|
| конвертирует в AVIF / WebP | в зависимости от поддержки браузера |
| генерирует несколько размеров | srcset автоматически; вы задаёте только sizes |
| lazy по умолчанию | priority для LCP-изображения |
| предотвращает CLS | требует width/height, статический импорт или fill |
| плейсхолдер | placeholder="blur" (автоматически при статическом импорте) |
| кэш | оптимизированные изображения кэшируются на сервере / CDN |
| Проп | Когда |
|---|---|
sizes |
всегда, если у изображения нет фиксированной ширины — иначе браузер может скачать самый большой вариант |
fill |
изображение заполняет родителя с position: relative и размерами (карточки, hero) |
quality |
75 по умолчанию; больше нужно редко |
images.remotePatterns в next.config.ts |
обязательно для изображений с других доменов (безопасность) |
Где хранить изображения
| Источник | Рекомендация |
|---|---|
| изображения проекта (логотип, иллюстрации) | в репозитории, статический импорт |
| загруженные пользователями | хранилище (S3, Vercel Blob, Cloudinary) + next/image с remotePatterns |
| много изображений, трансформации (обрезка, фильтры) | сервис изображений / CDN (Cloudinary, imgix) с собственным loader |
Чек-лист
- современный формат (AVIF / WebP), SVG для иконок
- правильный размер +
sizes - LCP-изображение с
priority, остальные — lazy -
width/heightилиfillвнутри родителя с размерами - осмысленный
altи имя файла (помогает и SEO) - никаких GIF — вместо них видео
muted autoplay loop playsinline
Коротко
- Изображения обычно определяют LCP и вес страницы.
- AVIF/WebP, правильный размер, качество ~75–85, lazy ниже экрана,
priorityдля LCP, зарезервированные размеры. next/imageделает почти всё сам — вы задаётеalt,sizesиpriority.