Компонент next/image не отдаёт исходный /hero.jpg напрямую: URL переписывается в /_next/image?url=...&w=...&q=..., строится srcset, оптимизатор ресайзит и транскодирует в AVIF/WebP, результат кэшируется.
Разбор
Первый запрос — cache miss (медленнее), последующие — быстро с CDN. Размеры обязательны — они задают aspect-ratio, браузер резервирует место и не сдвигает layout (CLS).
Три способа указать размеры:
- Static import —
import hero from './hero.jpg'; Next читает intrinsic size на билде и генерирует blur placeholder.
- Явные
width/height — для remote/string src.
fill — абсолютное позиционирование в position: relative родителе; размер через CSS, обязателен sizes.
sizes — самый недооценённый prop: говорит браузеру, как широко картинка реально отрисуется на breakpoint, чтобы выбрать правильный srcset. Без него fill ведёт себя как 100vw и качает максимальный размер на телефоне.
priority отключает lazy-load и добавляет preload — только для LCP-изображения (обычно hero).
Remote images должны быть в images.remotePatterns — защита от SSRF, иначе оптимизатор станет открытым прокси.
Итог
next/image — это CDN-пайплайн + контракт на aspect ratio; без явных размеров или sizes теряется главная выгода — стабильность layout и экономия байт.