Перейти к основному содержимому

Next.js

Для чего модуль

Научиться проектировать Next.js-приложение как production-систему: с понятными границами server/client, предсказуемым кэшем и управляемой стоимостью рендера.

Результат после прохождения

  1. Вы осознанно выбираете SSR/SSG/ISR/dynamic rendering под конкретный экран.
  2. Вы управляете revalidate, tag/path invalidation и не получаете «случайно устаревший UI».
  3. Вы проектируете границы между Server/Client Components без лишнего JS в браузере.
  4. Вы умеете диагностировать hydration и data-fetching проблемы через воспроизводимый runbook.

Термины и аббревиатуры

ТерминКоротко
App RouterМаршрутизация Next.js
ISRИнкрементальное обновление
StreamingЧастичная отправка HTML
RevalidationОбновление кэша
TTFBВремя до первого байта

Фокус по грейдам

  1. Junior: понимать базовые механики и объяснять их простыми примерами.
  2. Middle: применять тему в продуктовых сценариях с учетом рисков и ограничений.
  3. Senior: управлять архитектурными trade-offs, метриками и эволюцией решения.

Как работать с модулем

  1. Берите один реальный экран и прогоняйте его через все уроки.
  2. Каждый архитектурный выбор фиксируйте через trade-off: UX, SEO, latency, стоимость сопровождения.
  3. Для каждой гипотезы делайте замер до/после, а не «ощущение, что стало лучше».

Программа модуля

Урок 1. App Router и архитектура

Цель: строить структуру Next-приложения так, чтобы она масштабировалась без хаоса.

Ментальная модель App Router

  1. layout.tsx задает каркас и может переиспользоваться между маршрутами.
  2. page.tsx отвечает за конкретный route-level UI.
  3. route.ts (Route Handlers) — backend-граница внутри Next.
  4. Server Components — default; Client Components — только где нужен браузерный runtime.

Server vs Client boundaries

Простой критерий:

  1. Нужен доступ к browser API/hooks событий? Это use client.
  2. Нужны секреты/бэкенд-запросы/уменьшение JS bundle? Оставляйте server-side.
// app/users/page.tsx (Server Component)
import UsersList from './UsersList';

export default async function UsersPage() {
const users = await fetchUsers();
return <UsersList initialUsers={users} />;
}

// app/users/UsersList.tsx
'use client';

Где ломается в проде

  1. use client ставится слишком высоко по дереву и тянет лишний JS.
  2. Бизнес-логика размазывается между route и component слоями.
  3. Непрозрачные импорты: server module попадает в client bundle.

Мини-задача (обязательная)

Разбейте один сложный экран на Server/Client Components. Для каждой границы дайте аргумент: что выигрываем и какой риск получаем.

Что спросит интервьюер: когда use client обязателен, а когда это лишний JS в браузере.

Критерий готовности по уроку: вы можете объяснить структуру App Router модуля так, чтобы новый разработчик без боли продолжил работу.

Урок 2. Рендер и кэш

Цель: выбирать стратегию рендера и кэша через требования, а не привычку.

Карта рендер-стратегий

  1. SSG — контент почти статичен, важны скорость и SEO.
  2. ISR — контент меняется периодически, нужен баланс свежести и цены.
  3. SSR/dynamic — данные зависят от пользователя/контекста запроса.
  4. CSR — интерактивные зоны, где серверный рендер не дает выгоды.

Revalidation и инвалидация

await fetch('https://api.example.com/products', {
next: { revalidate: 300, tags: ['products'] },
});

// после мутации
revalidateTag('products');

Ключевая мысль: кэш без стратегии инвалидции почти всегда превращается в баг с устаревшими данными.

Freshness vs latency vs cost

  1. Максимальная свежесть = больше server work и выше cost.
  2. Агрессивный кэш = быстрее, но выше риск stale UI.
  3. Правильный баланс зависит от бизнес-критичности данных.

Где ломается в проде

  1. Один и тот же endpoint рендерится в разных режимах без единой политики.
  2. Нет понятных правил, какие данные «могут стареть», а какие нет.
  3. После мутаций забывают инвалидировать нужные path/tag.

Мини-задача (обязательная)

Для 4 страниц (лендинг, каталог, карточка товара, личный кабинет) выберите рендер-режим и cache policy с аргументацией.

Что спросит интервьюер: почему выбран SSR/SSG/ISR и как вы это проверили метриками.

Критерий готовности по уроку: вы можете защитить стратегию рендера через бизнес-требования и замеры.

Урок 3. Data fetching и UX

Цель: сделать UX устойчивым к задержкам, ошибкам и частично доступным данным.

Loading/Error/Empty как контракт

На каждом data route должны быть продуманы состояния:

  1. loading.tsx — что пользователь видит во время ожидания.
  2. error.tsx — как восстанавливаться после сбоя.
  3. empty-state — как объяснить отсутствие данных.

Streaming и progressive rendering

Streaming полезен, когда часть экрана можно показать раньше, не дожидаясь медленного блока данных.

Hydration mismatch: причины и профилактика

  1. Нестабильные значения на сервере и клиенте (Date.now, random).
  2. Разная логика форматирования/локали.
  3. Побочные эффекты в render-phase.
// Плохо: нестабильное значение прямо в рендере
<p>{Date.now()}</p>

Где ломается в проде

  1. При ошибке API экран «молча пустой» вместо контролируемого fallback.
  2. Loading-компонент не отражает реальную структуру экрана -> скачки layout.
  3. Ошибка в Route Handler маскируется generic 500 без trace context.

Мини-задача (обязательная)

Реализуйте страницу с loading.tsx, error.tsx и пустым состоянием. Добавьте один кейс hydration mismatch и зафиксируйте, как вы его устранили.

Что спросит интервьюер: как вы предотвращаете hydration mismatch в сложных экранах.

Критерий готовности по уроку: вы можете показать стабильный UX при медленной сети и объяснить, почему он устойчив.

Урок 4. Reliability и delivery

Цель: довести Next-приложение до эксплуатационного уровня.

Auth и security boundary

  1. Не держите чувствительную логику в client-only слое без причины.
  2. Четко разделяйте публичные и защищенные маршруты.
  3. Для критичных операций добавляйте audit trail и trace correlation.

Perf budgets и контроль деградации

  1. Для ключевых маршрутов задайте budgets по TTFB/LCP/INP.
  2. Любая оптимизация проходит через baseline и повторный замер.
  3. Релиз блокируется при нарушении критичных budget порогов.

Observability и rollback

  1. Логи фронта и route handlers должны коррелироваться по trace/request id.
  2. Есть playbook: что делаем при росте ошибок/latency.
  3. Rollback — это заранее подготовленная процедура, а не импровизация.

Мини-задача (обязательная)

Подготовьте Next release checklist: кэш, auth, CWV budgets, error-rate, rollout strategy, rollback conditions.

Что спросит интервьюер: какие риски вы видите при росте проекта и как их закроете.

Критерий готовности по уроку: вы можете описать эксплуатационный контур Next-приложения и доказать, что он снижает риск инцидентов.

Практика

  1. Пройдите Next.js вопросы.
  2. Подготовьте таблицу выбора SSR/SSG/ISR/dynamic для 6 реальных экранов.
  3. Реализуйте демо с loading.tsx, error.tsx, empty-state и контролируемым revalidation.
  4. Сделайте мини-отчет: baseline и after по одному критичному маршруту.
  5. Закрепите в Песочнице сценарий «мутация + корректная инвалидация кэша».

Связь с треками и вопросами

  1. Треки: Middle трек, Senior трек.
  2. Вопросы: Next.js, Senior Frontend.
  3. Повторение: 3-5 вопросов без подсказок -> сверка с модулем -> повтор через 24 часа.

Критерий готовности

Вы можете защищать Next-архитектуру как инженерное решение: контекст -> выбор -> риск -> метрика -> план эксплуатации.

Артефакты после модуля

  1. Таблица рендер-стратегий по маршрутам продукта.
  2. Cache policy документ с правилами инвалидции.
  3. Runbook по hydration/data-fetching инцидентам.
  4. Набор из 6 сильных interview-ответов по Next.js.

Куда дальше

  1. Frontend-архитектура
  2. Frontend System Design
  3. Next.js