SSR、SSG、CSR:三种渲染模式全面解析

SSR、SSG、CSR:三种渲染模式全面解析
在现代 Web 开发中,页面渲染模式的选择直接影响用户体验、SEO 效果和开发效率。本文将深入对比 SSR(服务端渲染)、SSG(静态站点生成) 和 CSR(客户端渲染) 三种主流方案,帮助你在实际项目中做出最佳选择。
什么是 CSR(Client-Side Rendering)
CSR 即客户端渲染,是 SPA(Single Page Application)的核心模式。服务器只返回一个空的 HTML 骨架和 JavaScript 文件,所有渲染逻辑都在浏览器端完成。
工作流程
浏览器请求 → 服务器返回空 HTML + JS → 浏览器下载并执行 JS → API 请求数据 → 渲染页面
代码示例
"use client";
import { useEffect, useState } from "react";
export default function PostList() {
const [posts, setPosts] = useState([]);
useEffect(() => {
fetch("/api/posts")
.then((res) => res.json())
.then((data) => setPosts(data));
}, []);
return (
<ul>
{posts.map((post) => (
<li key={post.id}>{post.title}</li>
))}
</ul>
);
}
优点
- 交互体验好:页面切换无需重新加载,过渡流畅
- 服务器压力小:渲染工作由客户端承担
- 前后端分离:开发职责清晰
缺点
- 首屏加载慢:需要下载、解析、执行 JS 后才能看到内容
- SEO 不友好:搜索引擎爬虫可能无法正确抓取动态内容
- 白屏时间长:JS 加载期间用户看到的是空白页面
什么是 SSR(Server-Side Rendering)
SSR 即服务端渲染,每次请求时服务器实时生成完整的 HTML 页面返回给浏览器,随后客户端 JS 接管交互(Hydration)。
工作流程
浏览器请求 → 服务器获取数据 + 渲染 HTML → 返回完整 HTML → 浏览器展示 → JS Hydration 激活交互
代码示例(Next.js App Router)
// app/posts/page.tsx — 默认就是 Server Component
import { prisma } from "@/lib/db";
export default async function PostsPage() {
const posts = await prisma.post.findMany({
where: { published: true },
orderBy: { publishedAt: "desc" },
});
return (
<ul>
{posts.map((post) => (
<li key={post.id}>{post.title}</li>
))}
</ul>
);
}
优点
- 首屏渲染快:用户立即看到完整内容
- SEO 友好:搜索引擎可直接抓取完整 HTML
- 数据实时性:每次请求都能获取最新数据
缺点
- 服务器压力大:每个请求都需要服务器实时渲染
- TTFB 较长:服务器处理时间影响首字节到达时间
- 需要 Node.js 服务器:不能部署到纯静态托管
什么是 SSG(Static Site Generation)
SSG 即静态站点生成,在构建时(build time)预先生成所有页面的 HTML 文件,部署后直接由 CDN 分发静态文件。
工作流程
构建时获取数据 + 渲染 HTML → 生成静态文件 → 部署到 CDN → 浏览器请求 → CDN 直接返回 HTML
代码示例(Next.js App Router)
// app/posts/[slug]/page.tsx
import { prisma } from "@/lib/db";
// 构建时生成所有文章路径
export async function generateStaticParams() {
const posts = await prisma.post.findMany({
where: { published: true },
select: { slug: true },
});
return posts.map((post) => ({ slug: post.slug }));
}
export default async function PostPage({
params,
}: {
params: { slug: string };
}) {
const post = await prisma.post.findUnique({
where: { slug: params.slug },
});
return (
<article>
<h1>{post?.title}</h1>
<div>{post?.content}</div>
</article>
);
}
优点
- 性能极致:静态文件通过 CDN 分发,响应速度最快
- 安全性高:没有服务端运行时,减少攻击面
- 成本极低:可部署到任意静态托管平台(Vercel、Netlify、GitHub Pages)
- SEO 友好:完整的 HTML 内容
缺点
- 数据时效性差:内容更新需要重新构建部署
- 构建时间长:页面数量多时,构建过程耗时
- 不适合动态内容:实时数据展示场景不适用
三种模式对比
| 特性 | CSR | SSR | SSG |
|---|---|---|---|
| 首屏速度 | 慢 ❌ | 快 ✅ | 最快 ✅✅ |
| SEO | 差 ❌ | 好 ✅ | 好 ✅ |
| 数据实时性 | 实时 ✅ | 实时 ✅ | 构建时 ❌ |
| 服务器压力 | 低 ✅ | 高 ❌ | 无 ✅✅ |
| 交互体验 | 优秀 ✅ | 良好 | 良好 |
| 部署要求 | 静态托管 | Node.js 服务器 | 静态托管/CDN |
| 构建速度 | 快 | — | 页面多时慢 |
| 典型框架 | React SPA, Vue SPA | Next.js, Nuxt.js | Astro, Hugo, Next.js |
混合渲染:现代框架的最佳实践
现代框架如 Next.js 并不要求你在三者中选一个,而是支持按页面粒度混合使用:
├── 首页 (/) → SSG + ISR(增量静态再生)
├── 文章详情 (/posts/[slug]) → SSG(构建时生成)
├── 搜索页 (/search) → CSR(纯客户端交互)
├── 管理后台 (/admin) → CSR(需要登录态)
└── 评论区 → SSR / CSR(实时数据)
ISR(Incremental Static Regeneration)
Next.js 提供的 ISR 模式结合了 SSG 和 SSR 的优点:
// 每 60 秒重新验证
export const revalidate = 60;
export default async function Page() {
const data = await fetch("https://api.example.com/data");
return <div>{/* 渲染数据 */}</div>;
}
ISR 让页面在构建时生成静态版本,同时在后台按设定的时间间隔重新生成,兼顾了性能和数据时效性。
如何选择?
根据项目特点选择合适的渲染模式:
- 博客 / 文档站 → SSG 为主,内容变更频率低,追求极致性能
- 电商 / 新闻 → SSR + ISR,兼顾 SEO 和数据时效
- 后台管理系统 → CSR,无需 SEO,重交互体验
- 社交 / 实时应用 → SSR + CSR 混合,首屏 SSR,后续交互 CSR
没有银弹,理解每种模式的取舍,才能做出最优架构决策。
总结
| 场景 | 推荐方案 |
|---|---|
| 内容为主、低更新频率 | SSG |
| 需要 SEO + 实时数据 | SSR |
| 纯交互、无 SEO 需求 | CSR |
| 综合型应用 | 混合渲染(Next.js) |
在 Next.js App Router 中,默认的 Server Component 天然支持 SSR/SSG,而 "use client" 标记的组件则走 CSR 路线。合理运用这些模式,能让你的应用在性能、SEO 和开发体验之间找到最佳平衡点。
▶评论
// 登录后即可参与讨论