
05. 渲染模式 - SSR、SSG、ISR、CSR概述Next.js 支持多种渲染模式每种模式有不同的特点和适用场景。选择合适的渲染模式可以显著提升应用性能、用户体验和 SEO。维度内容WhatNext.js 支持的四种渲染模式Why根据场景选择最佳渲染方式平衡性能和体验When不同页面类型使用不同渲染模式Where页面/路由级别配置Who需要优化页面加载的开发者HowSSR:export const dynamic force-dynamicSSG:export const dynamic force-staticISR:export const revalidate 36001. 渲染模式概览1.1 四种模式对比模式渲染时机HTML 生成缓存SEO适用场景SSR每次请求实时无✅ 好个性化内容SSG构建时静态永久✅ 最好博客、文档ISR构建时 定时静态 更新时间缓存✅ 好商品列表、新闻CSR客户端动态无⚠️ 差管理后台1.2 渲染流程对比SSR (Server-Side Rendering) 请求 → 服务器渲染 → HTML 响应 → 客户端水合 SSG (Static Site Generation) 构建 → 生成 HTML → 部署 → 直接响应 ISR (Incremental Static Regeneration) 构建 → 生成 HTML → 部署 → 请求 → 响应缓存 → 后台重新生成 CSR (Client-Side Rendering) 请求 → 空 HTML → 下载 JS → 渲染内容2. SSR (Server-Side Rendering)2.1 什么是 SSRSSR 在每个请求到达时在服务器上动态生成 HTML。// app/products/page.js // SSR: 每次请求都重新渲染 export const dynamic force-dynamic; async function ProductsPage() { // 每次请求都会执行 const products await fetch(https://api.example.com/products, { cache: no-store, // 确保每次都获取最新数据 }).then(res res.json()); return ( div h1商品列表/h1 p更新时间: {new Date().toLocaleString()}/p ProductList products{products} / /div ); } export default ProductsPage;2.2 SSR 适用场景// ✅ 适合 SSR 的场景 // - 个性化内容用户仪表盘 // - 实时数据股票价格 // - 需要认证的页面 // - SEO 重要且数据频繁变化 // app/dashboard/page.js export const dynamic force-dynamic; async function DashboardPage() { const user await getCurrentUser(); // 需要认证 const stats await getUserStats(user.id); // 个性化数据 return ( div h1欢迎回来, {user.name}/h1 Stats stats{stats} / /div ); }2.3 SSR 配置方式// 方式1使用 dynamic 配置 export const dynamic force-dynamic; // 方式2使用 fetch 的 no-store fetch(url, { cache: no-store }); // 方式3使用 cookies() 或 headers() 会自动转为动态 export default async function Page() { const cookie cookies(); // 自动转为动态渲染 const data await fetch(https://api.example.com/data); return div{data}/div; }3. SSG (Static Site Generation)3.1 什么是 SSGSSG 在构建时生成静态 HTML部署后直接响应请求。// app/about/page.js // SSG: 构建时生成静态页面 export const dynamic force-static; async function AboutPage() { // 构建时执行一次 const companyInfo await fetch(https://api.example.com/company, { cache: force-cache, }).then(res res.json()); return ( div h1关于我们/h1 p{companyInfo.description}/p /div ); } export default AboutPage;3.2 动态 SSG (generateStaticParams)// app/blog/[slug]/page.js // 生成所有静态路径 export async function generateStaticParams() { const posts await fetch(https://api.example.com/posts).then(res res.json()); return posts.map(post ({ slug: post.slug, })); } // SSG 模式 export const dynamic force-static; async function BlogPostPage({ params }) { const { slug } await params; const post await fetch(https://api.example.com/posts/${slug}).then(res res.json()); return ( article h1{post.title}/h1 p{post.content}/p /article ); } export default BlogPostPage;3.3 SSG 适用场景// ✅ 适合 SSG 的场景 // - 博客文章 // - 文档网站 // - 营销页面 // - 产品目录数据变化不频繁 // app/docs/[...slug]/page.js export async function generateStaticParams() { const docs await getAllDocs(); return docs.map(doc ({ slug: doc.path.split(/), })); } export const dynamic force-static;4. ISR (Incremental Static Regeneration)4.1 什么是 ISRISR 结合了 SSG 和 SSR 的优点构建时生成静态页面并定时在后台重新生成。// app/products/page.js // ISR: 每 60 秒重新验证 export const revalidate 60; // 60 秒后重新生成 async function ProductsPage() { const products await fetch(https://api.example.com/products, { next: { revalidate: 60 }, }).then(res res.json()); return ( div h1商品列表/h1 p最后更新: {new Date().toLocaleString()}/p ProductList products{products} / /div ); } export default ProductsPage;4.2 按需 ISR (On-Demand ISR)// app/api/revalidate/route.js import { revalidatePath, revalidateTag } from next/cache; import { NextResponse } from next/server; export async function POST(request) { const { path, tag } await request.json(); // 重新验证特定路径 if (path) { revalidatePath(path); } // 重新验证特定标签 if (tag) { revalidateTag(tag); } return NextResponse.json({ revalidated: true }); }// app/products/page.js async function ProductsPage() { const products await fetch(https://api.example.com/products, { next: { tags: [products] }, // 添加标签 }).then(res res.json()); return ProductList products{products} /; } // 当产品更新时调用 API 触发重新验证 // fetch(/api/revalidate, { method: POST, body: JSON.stringify({ tag: products }) })4.3 ISR 配置选项// app/products/[id]/page.js // 方式1使用 revalidate 配置 export const revalidate 3600; // 1 小时 // 方式2使用 fetch 的 next.revalidate async function ProductPage({ params }) { const product await fetch(https://api.example.com/products/${params.id}, { next: { revalidate: 3600 }, }).then(res res.json()); return ProductDetail product{product} /; } // 方式3结合 generateStaticParams export async function generateStaticParams() { const products await fetch(https://api.example.com/products).then(res res.json()); return products.map(product ({ id: product.id.toString(), })); } export const revalidate 3600; // 预先构建的页面也会重新验证5. CSR (Client-Side Rendering)5.1 什么是 CSRCSR 在客户端渲染内容服务器只返回空的 HTML 骨架。// app/dashboard/page.js use client; import { useState, useEffect } from react; // 客户端渲染 export const dynamic force-dynamic; export default function DashboardPage() { const [data, setData] useState(null); useEffect(() { fetch(/api/dashboard-data) .then(res res.json()) .then(setData); }, []); if (!data) return div加载中.../div; return Dashboard data{data} /; }5.2 CSR 适用场景// ✅ 适合 CSR 的场景 // - 需要认证的后台管理 // - 高度交互的应用 // - 不需要 SEO 的页面 // - 受保护的页面 // app/admin/page.js use client; import { useSession } from next-auth/react; import { useRouter } from next/navigation; export default function AdminPage() { const { data: session, status } useSession(); const router useRouter(); if (status loading) return div加载中.../div; if (!session) { router.push(/login); return null; } return AdminDashboard /; }6. 混合渲染模式6.1 页面级混合// app/blog/page.js - SSG // 博客列表页使用 SSG export const dynamic force-static; async function BlogPage() { const posts await getPosts(); return PostList posts{posts} /; } // app/blog/[slug]/page.js - ISR // 博客详情页使用 ISR export const revalidate 3600; async function BlogPostPage({ params }) { const post await getPost(params.slug); return PostDetail post{post} /; } // app/user/profile/page.js - SSR // 用户资料页使用 SSR export const dynamic force-dynamic; async function ProfilePage() { const user await getCurrentUser(); return UserProfile user{user} /; }6.2 组件级混合// app/products/page.js import { Suspense } from react; async function ProductList() { // 静态数据 - SSG const categories await fetch(https://api.example.com/categories, { cache: force-cache, }).then(res res.json()); return CategoryList categories{categories} /; } async function LiveStats() { // 动态数据 - SSR const stats await fetch(https://api.example.com/live-stats, { cache: no-store, }).then(res res.json()); return Stats stats{stats} /; } // 页面使用 SSG但内部组件动态加载 export const dynamic force-static; export default function ProductsPage() { return ( div Suspense fallback{div加载分类.../div} ProductList / /Suspense Suspense fallback{div加载实时数据.../div} LiveStats / /Suspense /div ); }7. 渲染模式选择指南7.1 决策树需要 SEO │ ├─ 是 → 数据变化频率 │ │ │ ├─ 从不变化 → SSG │ ├─ 偶尔变化 → ISR │ └─ 频繁变化 → SSR │ └─ 否 → 是否需要快速首屏 │ ├─ 是 → 用户认证 │ │ │ ├─ 是 → SSR │ └─ 否 → SSG/ISR │ └─ 否 → CSR7.2 场景推荐场景推荐模式理由博客文章SSG内容不变SEO 重要产品列表ISR价格库存可能变化用户仪表盘SSR个性化数据需要认证管理后台CSR不需要 SEO交互多帮助文档SSG内容静态SEO 重要新闻网站ISR内容定时更新电商首页ISR促销信息定时更新实时看板SSR需要实时数据8. 完整示例电商网站// app/layout.js import { Inter } from next/font/google; import ./globals.css; const inter Inter({ subsets: [latin] }); export const metadata { title: 我的商店, description: 最好的购物体验, }; export default function RootLayout({ children }) { return ( html langzh-CN body className{inter.className} Header / {children} Footer / /body /html ); } // app/page.js - 首页 (SSG ISR 部分) import { Suspense } from react; import HeroBanner from ./components/HeroBanner; import ProductGrid from ./components/ProductGrid; import FlashSale from ./components/FlashSale; // 静态部分 - SSG async function Categories() { const categories await fetch(https://api.example.com/categories, { cache: force-cache, }).then(res res.json()); return CategoryList categories{categories} /; } // 准实时部分 - ISR async function RecommendedProducts() { const products await fetch(https://api.example.com/products/recommended, { next: { revalidate: 3600, tags: [recommended] }, }).then(res res.json()); return ProductGrid products{products} title推荐商品 /; } // 动态部分 - SSR async function FlashSaleProducts() { const products await fetch(https://api.example.com/flash-sale, { cache: no-store, }).then(res res.json()); return FlashSale products{products} /; } // 主页 export const dynamic force-static; export default function HomePage() { return ( main HeroBanner / Suspense fallback{div加载分类.../div} Categories / /Suspense Suspense fallback{div加载推荐.../div} RecommendedProducts / /Suspense Suspense fallback{div加载限时秒杀.../div} FlashSaleProducts / /Suspense /main ); } // app/products/[id]/page.js - 商品详情 (ISR) export async function generateStaticParams() { // 预先生成热门商品的静态页面 const hotProducts await fetch(https://api.example.com/products/hot).then(res res.json()); return hotProducts.map(product ({ id: product.id.toString(), })); } // ISR: 60 秒后重新验证 export const revalidate 60; async function ProductPage({ params }) { const { id } await params; const product await fetch(https://api.example.com/products/${id}, { next: { revalidate: 60, tags: [product-${id}] }, }).then(res res.json()); if (!product) notFound(); return ( div classNameproduct-detail ProductImages images{product.images} / ProductInfo product{product} / ProductReviews productId{id} / /div ); } // app/cart/page.js - 购物车 (SSR) export const dynamic force-dynamic; async function CartPage() { // 需要认证和实时数据 const cart await getCurrentUserCart(); return ( div h1购物车/h1 CartItems items{cart.items} / CartSummary total{cart.total} / /div ); } // app/admin/page.js - 管理后台 (CSR) use client; import { useSession } from next-auth/react; import { useRouter } from next/navigation; export default function AdminPage() { const { data: session, status } useSession(); const router useRouter(); if (status loading) return div加载中.../div; if (!session) { router.push(/login); return null; } return AdminDashboard /; }9. 总结核心要点模式配置特点适用场景SSRdynamic: force-dynamic实时、个性化用户仪表盘SSGdynamic: force-static极快、SEO 好博客、文档ISRrevalidate: n平衡、更新产品列表CSRuse client交互多管理后台记忆口诀SSG 最快 SEO 好内容不变用它棒ISR 中间带更新准实时内容强SSR 实时个性化用户数据动态强CSR 交互最丰富后台管理很在行10. 相关资源Next.js 渲染模式ISR 文档generateStaticParams