Оптимизация изображений (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 под капотом

1

Конвертация формата

Автоматически конвертирует в WebP или AVIF, если браузер их поддерживает. Это уменьшает размер файла на 30-50%.

2

Ресайз под устройство

Генерирует несколько вариантов изображения разного размера. Браузер загружает только подходящий.

3

Lazy loading

По умолчанию изображения загружаются лениво: только когда попадают в viewport. Это ускоряет начальную загрузку страницы.

4

Предотвращение 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 оптимизации изображений.

Полезные ресурсы

Связанные темы