Виды рендеринга в Next.js
April 1, 2025
Next.js 15 предоставляет гибкую систему рендеринга, которая позволяет достичь как высокой производительности, так и хорошего SEO. В этой статье разберём основные методы рендеринга, их плюсы, особенности использования, влияние на SEO и современную возможность стриминга с помощью React Server Components.
1. Static Site Generation (SSG) — Статическая генерация
- HTML генерируется на этапе сборки (build time)
- Очень быстрая загрузка, отлично кэшируется
- Используется для редко меняющегося контента
Пример:
// app/blog/[slug]/page.tsx export const dynamic = 'error'; export async function generateStaticParams() { const posts = await fetchPosts(); return posts.map((post) => ({ slug: post.slug })); } export default async function BlogPost({ params }: { params: { slug: string } }) { const post = await getPost(params.slug); return <article>{post.title}</article>; }
dynamic = 'error' — запрет динамического рендеринга
Если во время рендеринга страницы Next.js обнаружит что-либо, требующее динамического рендеринга (например, cookies(), headers(), fetch(..., { cache: 'no-store' }), useSearchParams() и т.д.), то вызовется ошибка сборки или выполнения.
Для чего это нужно?
- Гарантирует, что страница полностью статическая (SSG)
- Полезно для SEO и быстрой загрузки
- Помогает поймать ошибочные или неожиданные динамические зависимости
2. Server-Side Rendering (SSR) — Рендеринг на сервере
- HTML создаётся на каждый запрос
- Используется для часто обновляющихся данных
Пример:
// app/dashboard/page.tsx export const dynamic = 'force-dynamic'; export default async function Dashboard() { const stats = await fetchStats(); return <div>Активные пользователи: {stats.activeUsers}</div>; }
force-dynamic вынуждает страницу всегда рендериться на сервере при каждом запросе — то есть включает Server-Side Rendering (SSR) даже если данные могли бы быть закэшированы или предрендерены.
Если в компоненте используются cookies, headers, useSearchParams, данные, зависящие от времени запроса (request-time data), или вызывается unstable_noStore(), Next.js автоматически применяет режим динамического рендеринга (force-dynamic). Однако, при необходимости, этот режим можно задать явно с помощью export const dynamic = 'force-dynamic'.
Когда и зачем использовать force-dynamic?
- Страница зависит от данных, которые часто меняются
- Ты не хочешь кэширования
- Используешь запросы к базе данных, API, которые возвращают свежие данные каждый раз
3. Incremental Static Regeneration (ISR) — Инкрементальная регенерация
- HTML создаётся при сборке и обновляется в фоне через указанное время
- Компромисс между SSG и SSR
Пример:
// app/news/page.tsx export const revalidate = 60; // обновлять раз в минуту export default async function NewsPage() { const news = await getLatestNews(); return ( <ul> {news.map((n) => ( <li key={n.id}>{n.title}</li> ))} </ul> ); }
4. Client-Side Rendering (CSR) — Рендеринг на клиенте
- Компонент загружается без данных, затем делает fetch на клиенте
- Используется для интерактивных компонентов
Пример:
// app/profile/client-profile.tsx 'use client'; import { useEffect, useState } from 'react'; export default function ClientProfile() { const [user, setUser] = useState(null); useEffect(() => { fetch('/api/me') .then((res) => res.json()) .then(setUser); }, []); if (!user) return <p>Загрузка...</p>; return <p>Привет, {user.name}!</p>; }
SEO и рендеринг
Метод (полное название) | SEO-дружелюбность | Комментарий |
---|---|---|
SSG (Static Site Generation) | Да | HTML уже готов — поисковики видят всё |
SSR (Server-Side Rendering) | Да | HTML отрендерен на сервере при запросе |
ISR (Incremental Static Regeneration) | Да | Почти как SSG, HTML обновляется, но всегда есть |
CSR (Client-Side Rendering) | Нет | HTML пустой, контент появляется только после загрузки JS |
Для хорошего SEO старайтесь использовать SSG, SSR или ISR. CSR подходит для вспомогательных компонентов, но не для основной страницы.
Streaming и React Server Components
Streaming в Next.js позволяет отображать часть страницы сразу, пока другие компоненты ещё загружаются. Это делается с помощью <Suspense> и React Server Components.
Пример Streaming:
// app/products/page.tsx import { Suspense } from 'react'; import FastSection from './FastSection'; import SlowSection from './SlowSection'; export default function ProductsPage() { return ( <> <h1>Каталог товаров</h1> <FastSection /> <Suspense fallback={<p>Загрузка рекомендаций...</p>}> <SlowSection /> </Suspense> </> ); }
// app/products/SlowSection.tsx export default async function SlowSection() { const recommendations = await fetchRecommendations(); return ( <div> {recommendations.map((r) => ( <p key={r.id}>{r.title}</p> ))} </div> ); }
Suspense позволяет Next.js отправить HTML части страницы сразу, не дожидаясь завершения всех async-компонентов.
- Гранулярный контроль стриминга с помощью <Suspense>: оборачивайте отдельные компоненты, чтобы управлять порядком загрузки и приоритетами.
- React Server Components позволяют не только стримить, но и сократить объём JS-кода на клиенте.
- Кэширование данных и повторное использование улучшает производительность и снижает нагрузку на сервер.
Заключение
- Выбирайте метод рендеринга под задачу: SSG — для контента, SSR — для динамики, ISR — компромисс, CSR — для интерактива.
- Для SEO важен серверный HTML (SSG/SSR/ISR).
- Streaming + Suspense = быстрый UX и плавный рендеринг.
Next.js даёт невероятную гибкость. Вы можете комбинировать подходы, выносить интерактив в клиентские компоненты и строить производительные и SEO-дружественные приложения.