90% 的前端都搞错了 SSR 和 SSG!前端渲染的“不可能三角”,才是你该理解的本质

6 阅读5分钟

🧩 一、一切的起点:我写的页面,为什么 SEO 差、首屏慢?

刚入行时,我以为前端就是:

function App() {
  const [data, setData] = useState([]);
  useEffect(() => {
    axios.get('/api/list').then(res => setData(res.data));
  }, []);
  return <div>{data.map(item => <p>{item.title}</p>)}</div>;
}

上线后,老板问:“为什么百度搜不到我们的商品?”
产品经理问:“用户打开首页要等 3 秒,能不能快点?”

我懵了——我的代码明明跑得好好的啊!

后来才知道:我用的是 CSR(客户端渲染) ,而搜索引擎和用户,看到的只是一个空壳 HTML:

<div id="root"></div>
<script src="main.js"></script>

内容?等 JS 加载完再说吧。

于是,我开始听说 SSRSSG 这些词。但它们到底是什么?为什么要有三种?能不能统一?
带着这些问题,我花了半年时间,终于搞懂了前端渲染背后的真实逻辑

今天,我想用最直白的方式,告诉你:这不是三个技术名词,而是一个“不可能三角”的权衡游戏。


📜 二、发展历程:为什么会有这三种模式?

1. CSR(客户端渲染)—— React 的默认姿势

  • 起源:create-react-app、SPA(单页应用)流行。
  • 核心思想:所有逻辑交给浏览器,服务器只返回静态文件。
  • ✅ 优点:开发简单、部署方便(扔 CDN 就行)、交互灵活。
  • ❌ 缺点:首屏白屏、SEO 差、弱网体验崩

适合场景:后台管理系统、私有应用(如企业 OA、数据看板)。

2. SSR(服务端渲染)—— 回归 Web 本质

  • 起源:传统 PHP/JSP 时代,HTML 在服务器拼好再返回。
  • 复兴原因:SEO + 首屏性能 成为刚需(电商、内容平台)。
  • 核心思想:用户请求时,服务器用 React 渲染出完整 HTML
  • ✅ 优点:首屏快、SEO 友好、用户体验好。
  • ❌ 缺点:需要 Node.js 服务器、每次请求消耗 CPU、部署复杂

适合场景:商品详情页、新闻、用户个人主页。

3. SSG(静态生成)—— 极致性能的妥协

  • 起源:JAMStack 架构兴起(Git + CDN + Serverless)。
  • 核心思想:在构建时就把所有页面“烤”成 HTML,部署后直接当静态文件分发。
  • ✅ 优点:首屏极快、SEO 极佳、零服务器成本、全球 CDN 加速
  • ❌ 缺点:内容必须提前知道,无法实时更新

适合场景:博客、文档站、营销落地页。


💻 三、写代码有什么不同?关键就看这两个函数!

Next.js 为例(Umi 类似),你不需要改组件写法,只需决定是否导出特定函数:

✅ CSR(默认)

// pages/index.js
export default function Home() {
  const [user, setUser] = useState(null);
  useEffect(() => {
    fetch('/api/me').then(r => r.json()).then(setUser);
  }, []);
  return <div>{user?.name}</div>;
}
// → 没有 getStaticProps / getServerSideProps,就是 CSR!

✅ SSG(构建时生成)

export async function getStaticProps() {
  const posts = await fetchPosts(); // 构建时运行!
  return { props: { posts } };
}
export default function Home({ posts }) {
  return <div>{posts.map(...)}</div>; // 数据直接可用!
}

✅ SSR(请求时生成)

export async function getServerSideProps({ req }) {
  const user = await getUserFromCookie(req.headers.cookie); // 每次请求都查!
  return { props: { user } };
}
export default function Dashboard({ user }) {
  return <div>欢迎,{user.name}!</div>;
}

🔑 核心差异不在 JSX,而在数据获取时机
组件本身,永远是你熟悉的 React。


🛠️ 四、开发 vs 生产:完整链路拆解

开发环境(next dev

  • 所有模式由同一个开发服务器处理;
  • 动态判断页面是否有 getStaticProps / getServerSideProps
  • 实时模拟对应行为,无需构建

生产环境(next build + next start

模式构建产物部署方式请求路径
CSRindex.html + main.jsCDN / Nginx浏览器加载 JS → 渲染
SSG预生成的 page.html + JSCDN / 静态主机直接返回 HTML
SSRNode.js 应用Node 服务器 / Serverless服务器实时渲染 HTML

💡 SSG 和 CSR 可部署到 GitHub Pages;SSR 必须用 Vercel、自建服务器等支持 Node 的平台。


⚖️ 五、前端的“不可能三角”:这才是核心!

经过无数项目验证,我发现:

你无法同时满足以下三点:

  1. 首屏快 + SEO 好(用户/爬虫打开即见内容)
  2. 数据完全动态、实时(千人千面、随时变)
  3. 零服务器成本、纯静态部署(CDN 托管、无限扩展)

你只能 三选二

选择模式放弃什么
首屏快 + 静态部署SSG实时性
首屏快 + 实时数据SSR静态部署
实时数据 + 静态部署CSR首屏 & SEO

这不是技术缺陷,而是物理规律——就像 CAP 定理一样,是分布式系统的本质约束。


🌐 六、它们真的互相包含!混合渲染才是常态

现实中,没有哪个项目只用一种模式。聪明的做法是 按页面、甚至按模块混合使用

// 博客文章页:SSG + CSR
export async function getStaticProps({ params }) {
  const post = await getPost(params.slug); // 构建时生成文章
  return { props: { post } };
}

export default function Post({ post }) {
  const [comments, setComments] = useState([]);
  useEffect(() => {
    // 浏览器中动态加载评论(个性化内容)
    fetchComments(post.id).then(setComments);
  }, []);

  return (
    <>
      <article>{post.content}</article> {/* SSG 部分 */}
      <Comments comments={comments} />   {/* CSR 部分 */}
    </>
  );
}

首屏 SEO 友好(SSG) + 个性化交互(CSR) = 最佳平衡!

Next.js 甚至支持 ISR(增量静态再生) :SSG 页面在访问时自动后台更新,兼顾静态与动态。


🎯 七、给只会写页面的你:如何站在架构角度看问题?

下次接到需求,别急着写 useState,先问三个问题:

  1. 这个页面需要被搜索引擎收录吗?
    → 是:排除 CSR,考虑 SSG/SSR。
  2. 内容是否经常变化?是否依赖用户身份?
    → 是:SSR;否:SSG。
  3. 团队有没有运维 Node.js 服务器的能力?
    → 没有:优先 SSG + CSR 混合。

前端不再是“切图仔”,而是产品体验的第一道防线。


✨ 结语:技术没有银弹,只有权衡

SSR、SSG、CSR 不是三个孤立的技术,而是同一枚硬币的三面
它们的存在,不是为了增加你的学习负担,而是给你一把调节用户体验与工程成本的旋钮

当你理解了这个“不可能三角”,你就不再死记概念,而是能根据业务,做出最优选择

而这,正是从前端 coder 到 frontend architect 的第一步。


如果你觉得这篇文章帮你打通了任督二脉,欢迎点赞、收藏、转发!
让更多还在 useEffect 里打转的前端朋友,看见更大的世界。


#前端 #SSR #SSG #CSR #Nextjs #Umi #前端架构 #SEO #性能优化 #掘金创作