Next.jsJuniorTechnical
Как компонент Image в Next.js оптимизирует изображения?
next/image автоматически конвертирует изображения в WebP/AVIF, генерирует srcSet для разных экранов, добавляет lazy loading и резервирует место для предотвращения CLS. Удалённые домены нужно явно разрешить в remotePatterns.
Компонент Image в Next.js
Компонент next/image — это расширенный <img>, который автоматически оптимизирует изображения на лету через встроенный Image Optimization API.
Базовое использование
import Image from "next/image";
import profilePic from "./avatar.jpg"; // статический импорт
export function Avatar() {
return (
<Image
src={profilePic}
alt="User avatar"
width={64}
height={64}
priority // LCP-изображение — загружать сразу
/>
);
}
// Удалённое изображение — нужен домен в конфиге
export function RemoteImage() {
return (
<Image
src="https://cdn.example.com/photo.jpg"
alt="Photo"
width={800}
height={600}
sizes="(max-width: 768px) 100vw, 50vw"
/>
);
}
Что происходит под капотом
- Конвертация в WebP/AVIF — браузер получает оптимальный формат через
Acceptзаголовок. AVIF меньше WebP на 20-50%. - Ресайз под устройство — генерируются
srcSetдля экранов разных плотностей. Телефон с 375px экраном не скачивает 1920px изображение. - Lazy loading по умолчанию —
loading="lazy"добавляется автоматически, если не указанpriority. - Предотвращение layout shift — резервирует место под изображение через CSS до его загрузки, CLS = 0.
- Кеширование — оптимизированные варианты кешируются на диске и отдаются с
Cache-Control: public, max-age=31536000.
fill режим для изображений без известных размеров
export function HeroBanner() {
return (
<div style={{ position: "relative", width: "100%", height: "400px" }}>
<Image
src="/hero.jpg"
alt="Hero"
fill
style={{ objectFit: "cover" }}
sizes="100vw"
priority
/>
</div>
);
}
Настройка допустимых доменов
// next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
images: {
remotePatterns: [
{
protocol: "https",
hostname: "cdn.example.com",
pathname: "/images/**",
},
],
formats: ["image/avif", "image/webp"],
deviceSizes: [640, 750, 828, 1080, 1200, 1920],
},
};
module.exports = nextConfig;
Подводные камни
- Для удалённых изображений обязательно указывать домен в
remotePatterns— без этогоnext buildпроходит, но runtime возвращает 400. priorityнужно указывать только для LCP-изображения (первый экран). Если добавить его всем изображениям, потеряется смысл lazy loading.- При использовании
fillродительский элемент обязательно должен иметьposition: relative(или absolute/fixed) — иначе изображение не отображается. - Атрибут
sizesкритичен для производительности: без него Next.js генерирует srcSet, но браузер скачивает полноразмерное изображение. Всегда указывайте корректные breakpoints. - Image Optimization работает на сервере — на статическом экспорте (
output: "export")next/imageне работает без кастомногоloader. - SVG файлы не оптимизируются компонентом Image по умолчанию — используйте обычный
<img>или SVGR для SVG. - Кеш оптимизированных изображений хранится в
.next/cache/images— при деплое без сохранения кеша первые запросы будут медленными.
Common mistakes
- Не указывать
width/height(илиfill) — CLS - Забыть
remotePatternsдля внешних URL - Ставить
priorityна все изображения - Использовать
next/imageдля SVG-иконок
What the interviewer is testing
- Знает форматы AVIF/WebP и srcset
- Понимает значение
priorityи LCP - Умеет настроить
remotePatterns - Учитывает биллинг и кеш в production