SSG, SSR, ISR, Streaming, and Partial Prerendering (PPR).
Understanding how Next.js renders content determines performance and cost.
| Strategy | Ideal For | Data Freshness | Performance (TTFB) | Scaling Risk |
|---|---|---|---|---|
| SSG | Marketing, Docs, Blogs | Build Time | Instant (CDN) | None |
| ISR | E-commerce, CMS | Periodic (e.g., 60s) | (CDN) |
| Low (Background Rebuilds) |
| SSR | Dashboards, Auth Gates | Real-Time (Request) | Slow (Waits for Server) | Critical (1 Request = 1 Compute) |
| PPR | Personalized Apps | Hybrid | Instant (Shell) | Medium (Streaming Holes) |
<Suspense>.await everything in the root page.tsx.Behavior: Routes are rendered at build time.
Usage: Marketing pages, Blogs, Documentation.
Dynamic Routes: Use generateStaticParams to generate static pages for dynamic paths (e.g., /blog/[slug]).
export async function generateStaticParams() {
const posts = await getPosts();
return posts.map((post) => ({ slug: post.slug }));
}
cookies(), headers(), searchParams.fetch(..., { cache: 'no-store' }).export const dynamic = 'force-dynamic'.Problem: SSR blocks the entire page until all data is ready.
Solution: Wrap slow components in <Suspense>. Next.js instantly sends the initial HTML (static shell) and streams the slow content later.
<Suspense fallback={<Skeleton />}>
<SlowDashboard />
</Suspense>
export const revalidate = 3600; (in layout/page) or { next: { revalidate: 3600 } } (in fetch).revalidatePath('/posts') via Server Actions or Webhooks.export const experimental_ppr = true.export const runtime = 'edge'. Limited API, starts instantly, lower cost.