Перейти к содержимому
Производительность2 мин чтения

Next.js 16 App Router: чеклист производительности

Границы компонентов, изображения, кеш и шрифты — и то, что из чеклистов для 14‑й версии перестало быть верным.

Обновлено:

Статья опубликована только на русском.

Набор шагов, который делает производительность предсказуемой без «магии». Порядок важен: первые два пункта дают больше, чем все остальные вместе.

1. Границы компонентов

  • Тяжёлые блоки остаются серверными компонентами. Клиентские — только там, где действительно нужен интерактив; граница "use client" заражает всё вниз по дереву.
  • Код‑сплиттинг по маршрутам, dynamic() для виджетов, которые не нужны на первом экране.

2. Изображения

  • <Image /> с явными width и height и осмысленным sizes — иначе браузер тянет вариант под самый широкий брейкпоинт.
  • Ленивая загрузка всего, что ниже первого экрана; hero — наоборот, priority.

3. Кеш и данные

  • revalidate на страницах и запросах, длинные заголовки кеширования на статику с хешем в имени.
  • Тяжёлые вычисления — на сервер. Это не только быстрее, это минус килобайты JS у клиента.

4. Шрифты

import { Inter } from "next/font/google";

const inter = Inter({ subsets: ["latin", "cyrillic"], display: "swap" });

Подключение через next/font раскладывает шрифт в собственную статику и убирает из цепочки загрузки первого экрана сторонний домен вместе с его DNS, TLS и политикой приватности.

5. Мелочи, которые решают

  • preconnect — только к доменам, которые действительно участвуют в первой отрисовке. Список из восьми штук вредит.
  • Скелетоны вместо блокирующих спиннеров: макет не прыгает, когда данные приходят.
  • Меньше обработчиков и меньше работы в каждом — это напрямую про INP.

Что изменилось после Next.js 14

Чеклисты двухлетней давности верны по существу, но два места из них больше не компилируются:

  • params и searchParams стали промисами, их нужно дожидаться: const { slug } = await params;. Синхронное чтение свойства, как в примерах для 14‑й версии, не работает.
  • middleware.ts переименован в proxy.ts. Смысл файла тот же, меняются имя и импорты — но для проекта, переезжающего с 14‑й версии, это самый заметный разрыв.