Оптимизация изображений (next/image) в Next.js
Компонент Image из next/image автоматически оптимизирует изображения: конвертирует в современные форматы, подбирает размер под устройство и загружает лениво.
Почему не обычный img
Обычный <img> загружает исходное изображение целиком, независимо от размера экрана. На мобильном устройстве загрузится та же картинка в 2000px, что и на десктопе. Компонент Image решает эту проблему.
Базовое использование
import Image from 'next/image'
export default function ProblemCard() {
return (
<Image
src="/images/problem-preview.png"
alt="Превью задачи на Hack Frontend"
width={800}
height={400}
/>
)
}
Что делает Image под капотом
Конвертация формата
Автоматически конвертирует в WebP или AVIF, если браузер их поддерживает. Это уменьшает размер файла на 30-50%.
Ресайз под устройство
Генерирует несколько вариантов изображения разного размера. Браузер загружает только подходящий.
Lazy loading
По умолчанию изображения загружаются лениво: только когда попадают в viewport. Это ускоряет начальную загрузку страницы.
Предотвращение CLS
Резервирует место под изображение до его загрузки, предотвращая сдвиг контента (Cumulative Layout Shift).
Локальные изображения
Для локальных файлов Next.js определяет размеры автоматически:
import Image from 'next/image'
import banner from '@/public/images/HackFrontendBanner.png'
export default function Hero() {
return (
<Image
src={banner}
alt="Hack Frontend"
placeholder="blur"
/>
)
}
placeholder="blur" показывает размытое превью до загрузки. Для локальных изображений blur placeholder генерируется автоматически.
Заполнение контейнера (fill)
Когда размеры неизвестны заранее:
<div className="relative h-64 w-full">
<Image
src={user.avatar}
alt={user.name}
fill
className="object-cover rounded-lg"
sizes="(max-width: 768px) 100vw, 50vw"
/>
</div>
Свойство fill растягивает изображение на весь родительский контейнер. sizes подсказывает браузеру, какой вариант загрузить.
Свойство priority
Для изображений выше сгиба (above the fold), которые видны сразу:
<Image
src="/images/hero.png"
alt="Hero"
width={1200}
height={600}
priority
/>
priority отключает lazy loading и добавляет preload хинт. Используй только для LCP-изображений (1-2 на страницу).
Внешние изображения
Для внешних URL нужно настроить домены в next.config.js:
// next.config.js
module.exports = {
images: {
remotePatterns: [
{
protocol: 'https',
hostname: 'avatars.githubusercontent.com'
},
{
protocol: 'https',
hostname: 'images.unsplash.com'
}
]
}
}
Безопасность:
Всегда указывай конкретные домены в remotePatterns. Открытый доступ ко всем доменам создает риск злоупотреблений через API оптимизации изображений.
Полезные ресурсы
- nextjs.org/docs — Image Optimization
- Image API Reference