Next.js
Для чего модуль
Научиться проектировать Next.js-приложение как production-систему: с понятными границами server/client, предсказуемым кэшем и управляемой стоимостью рендера.
Результат после прохождения
- Вы осознанно выбираете SSR/SSG/ISR/dynamic rendering под конкретный экран.
- Вы управляете
revalidate, tag/path invalidation и не получаете «случайно устаревший UI». - Вы проектируете границы между Server/Client Components без лишнего JS в браузере.
- Вы умеете диагностировать hydration и data-fetching проблемы через воспроизводимый runbook.
Термины и аббревиатуры
| Термин | Коротко |
|---|---|
App Router | Маршрутизация Next.js |
ISR | Инкрементальное обновление |
Streaming | Частичная отправка HTML |
Revalidation | Обновление кэша |
TTFB | Время до первого байта |
Фокус по грейдам
Junior: понимать базовые механики и объяснять их простыми примерами.Middle: применять тему в продуктовых сценариях с учетом рисков и ограничений.Senior: управлять архитектурными trade-offs, метриками и эволюцией решения.
Как работать с модулем
- Берите один реальный экран и прогоняйте его через все уроки.
- Каждый архитектурный выбор фиксируйте через trade-off: UX, SEO, latency, стоимость сопровождения.
- Для каждой гипотезы делайте замер до/после, а не «ощущение, что стало лучше».
Программа модуля
Урок 1. App Router и архитектура
Цель: строить структуру Next-приложения так, чтобы она масшта бировалась без хаоса.
Ментальная модель App Router
layout.tsxзадает каркас и может переиспользоваться между маршрутами.page.tsxотвечает за конкретный route-level UI.route.ts(Route Handlers) — backend-граница внутри Next.- Server Components — default; Client Components — только где нужен браузерный runtime.
Server vs Client boundaries
Простой критерий:
- Нужен доступ к browser API/hooks событий? Это
use client. - Нужны секреты/бэкенд-запросы/уменьшение 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';
Где ломается в проде
use clientставится слишком высоко по дереву и тянет лишний JS.- Бизнес-логика размазывается между route и component слоями.
- Непрозрачные импорты: server module попадает в client bundle.
Мини-задача (обязательная)
Разбейте один сложный экран на Server/Client Components. Для каждой границы дайте аргумент: что выигрываем и какой риск получаем.
Что спросит интервьюер:
когда use client обязателен, а когда это лишний JS в браузере.
Критерий готовности по уроку: вы можете объяснить структуру App Router модуля так, чтобы новый разработчик без боли продолжил работу.
Урок 2. Рендер и кэш
Цель: выбирать стратегию рендера и кэша через требования, а не привычку.
Карта рендер-стратегий
- SSG — контент почти статичен, важны скорость и SEO.
- ISR — контент меняется периодически, нужен баланс свежести и цены.
- SSR/dynamic — данные зависят от пользователя/контекста запроса.
- CSR — интерактивные зоны, где серверный рендер не дает выгоды.
Revalidation и инвалидация
await fetch('https://api.example.com/products', {
next: { revalidate: 300, tags: ['products'] },
});
// после мутации
revalidateTag('products');
Ключевая мысль: кэш без стратегии инвалидции почти всегда превращается в баг с устаревшими данными.
Freshness vs latency vs cost
- Максимальная свежесть = больше server work и выше cost.
- Агрессивный кэш = быстрее, но выше риск stale UI.
- Правильный баланс зависит от бизнес-критичности данных.
Где ломается в проде
- Один и тот же endpoint рендерится в разных режимах без единой политики.
- Нет понятных правил, какие данные «могут стареть», а какие нет.
- После мутаций забывают инвалидировать нужные path/tag.
Мини-задача (обязательная)
Для 4 страниц (лендинг, каталог, карточка товара, личный кабинет) выберите рендер-режим и cache policy с аргументацией.
Что спросит интервьюер: почему выбран SSR/SSG/ISR и как вы это проверили метриками.
Критерий готовности по уроку: вы можете защитить стратегию рендера через бизнес-требования и замеры.
Урок 3. Data fetching и UX
Цель: сделать UX устойчивым к задержкам, ошибкам и частично доступным данным.
Loading/Error/Empty как контракт
На каждом data route должны быть продуманы состояния:
loading.tsx— что пользователь видит во время ожидания.error.tsx— как восстанавливаться после сбоя.- empty-state — как объяснить отсутствие данных.
Streaming и progressive rendering
Streaming полезен, когда часть экрана можно показать раньше, не дожидаясь медленного блока данных.
Hydration mismatch: причины и профилактика
- Нестабильные значения на сервере и клиенте (
Date.now, random). - Разная логика форматирования/локали.
- Побочные эффекты в render-phase.
// Плохо: нестабильное значение прямо в рендере
<p>{Date.now()}</p>
Где ломается в проде
- При ошибке API экран «молча пустой» вместо контролируемого fallback.
- Loading-компонент не отражает реальную структуру экрана -> скачки layout.
- Ошибка в Route Handler маскируется generic 500 без trace context.
Мини-задача (обязательная)
Реализуйте страницу с loading.tsx, error.tsx и пустым состоянием.
Добавьте один кейс hydration mismatch и зафиксируйте, как вы его устранили.
Что спросит интервьюер: как вы предотвращаете hydration mismatch в сложных экранах.
Критерий готовности по уроку: вы можете показать стабильный UX при медленной сети и объяснить, почему он устойчив.
Урок 4. Reliability и delivery
Цель: довести Next-приложение до эксплуатационного уровня.
Auth и security boundary
- Не держите чувствительную логику в client-only слое без причины.
- Четко разделяйте публичные и защищенные маршруты.
- Для критичных операций добавляйте audit trail и trace correlation.
Perf budgets и контроль деградации
- Для ключевых маршрутов задайте budgets по TTFB/LCP/INP.
- Любая оптимизация проходит через baseline и повторный замер.
- Релиз блокируется при нарушении критичных budget порогов.
Observability и rollback
- Логи фронта и route handlers должны коррелироваться по trace/request id.
- Есть playbook: что делаем при росте ошибок/latency.
- Rollback — это заранее подготовленная процедура, а не импровизация.
Мини-задача (обязательная)
Подготовьте Next release checklist: кэш, auth, CWV budgets, error-rate, rollout strategy, rollback conditions.
Что спросит интервьюер: какие риски вы видите при росте проекта и как их закроете.
Критерий готовности по уроку: вы можете описать эксплуатационный контур Next-приложения и доказать, что он снижает риск инцидентов.
Практика
- Пройдите Next.js вопросы.
- Подготовьте таблицу выбора SSR/SSG/ISR/dynamic для 6 реальных экранов.
- Реализуйте демо с
loading.tsx,error.tsx, empty-state и контролируемым revalidation. - Сделайте мини-отчет: baseline и after по одному критичному маршруту.
- Закрепите в Песочнице сценарий «мутация + корректная инвалидация кэша».
Связь с треками и вопросами
- Треки: Middle трек, Senior трек.
- Вопросы: Next.js, Senior Frontend.
- Повторение: 3-5 вопросов без подсказок -> сверка с модулем -> повтор через 24 часа.
Критерий готовности
Вы можете защищать Next-архитектуру как инженерное решение: контекст -> выбор -> риск -> метрика -> план эксплуатации.
Артефакты после модуля
- Таблица рендер-стратегий по маршрутам продукта.
- Cache policy документ с правилами инвалидции.
- Runbook по hydration/data-fetching инцидентам.
- Набор из 6 сильных interview-ответов по Next.js.