← [ BACK_TO_NOTES ]

React SSR、Hydration 与服务端组件

用“页面生成时机 × 组件执行位置”两条轴区分 SSR、SSG、CSR、Hydration 与 React Server Components,避免把 RSC 等同于 SSR、Client Component 等同于 CSR。

#frame #react #synthesis #growing

[!info] related notes

React SSR、Hydration 与服务端组件

为什么这组概念容易混

它们都涉及“服务器先做一部分工作”,但其实回答的是不同问题。

最稳的理解方式是把问题拆成两条轴:

轴 A:页面 / Route 什么时候得到可展示结果?
      Build time / Request time / Browser time

轴 B:组件实现代码需要在哪个环境执行?
      Server Component / Client Component

只要先分开这两条轴,Server Component = SSR、Client Component = CSR 这类错误就不会出现。

轴 A:页面生成时机

SSG / Static Rendering

页面主要结果在构建时或再验证时生成,之后可以直接从缓存/CDN 分发。

典型场景:官网、文档、相对稳定的内容页。

SSR / Request-time Dynamic Rendering

请求到来后,服务器结合当前请求上下文、用户、cookie 或最新数据生成页面结果。

典型场景:登录后 Dashboard、用户专属页面、需要请求时信息的页面。

CSR

主要内容依赖浏览器 JavaScript 在客户端生成或通过客户端请求补齐。

典型场景:纯 SPA 或某些强交互、服务端预渲染价值较低的区域。

这一条轴的核心问题是:

内容在什么时候被准备出来?

详见 CSR、SSR 与 SSG。

轴 B:组件执行位置

Server Component

实现逻辑留在服务器,可访问数据库、Secret、文件和内部服务;组件实现 JavaScript 不作为普通客户端组件代码进入浏览器 bundle。

Client Component

需要浏览器 JavaScript runtime,可以拥有状态、effect、事件和浏览器 API。

这一条轴的核心问题是:

这段组件代码需要哪一侧的运行时能力?

详见 React 服务端组件与客户端组件。

两条轴如何组合

最关键的是:它们可以自由组合,而不是一一对应。

Server Component
├── Build time 执行      → Static / SSG
└── Request time 执行    → Dynamic / SSR-like rendering

Client Component
├── 初始 UI 可预渲染      → HTML 先到达,再 Hydration
└── 也可以纯客户端运行    → CSR

因此必须记住:

Server Component ≠ SSR
Client Component ≠ CSR

Hydration 位于哪里

Hydration 不是第三种渲染模式,而是:

浏览器把已经存在的服务端/静态 HTML 与客户端组件逻辑重新接起来,使事件、状态和后续更新真正生效。

所以它更像一个“接管阶段”:

Server / build
   ↓
HTML 已经可见
   ↓
Client JavaScript 加载
   ↓
Hydration
   ↓
交互区域真正接活

注意:在 RSC 架构中,不是所有 Server Component 都需要 hydration。真正需要客户端运行时的是 Client Component 边界及其客户端子树。

一个 Next.js 例子

/dashboard

DashboardPage         Server Component
├── UserSummary       Server Component
├── TaskList          Server Component
└── ThemeSwitcher     Client Component

如果这个 Dashboard 必须根据当前用户和请求时最新任务渲染:

  • Route 更接近 request-time dynamic rendering / SSR。
  • DashboardPage、UserSummary、TaskList 仍然是 Server Components。
  • ThemeSwitcher 是 Client Component。
  • ThemeSwitcher 的存在并不会让整个页面变成 CSR。

这就是两条轴真正分开的结果。

RSC Payload 为什么存在

React Server Components 不只是把一大段静态 HTML 扔给浏览器。框架还需要传递可以描述服务端组件结果、Client Component 位置和 props 等信息的 RSC 数据。

可以粗略理解为:

Server Components
      ↓
RSC representation / payload
      +
initial HTML(首屏)
      +
Client Component JS

HTML 负责尽快可见;RSC 数据帮助 React 维持组件树与后续导航;Client JavaScript 负责需要交互的部分。

与传统 SSR 的核心差异

传统 SSR 常见模式是:

整个 React tree 在服务器产 HTML
        ↓
整个需要交互的应用 JS 到客户端
        ↓
Hydrate 大片组件树

RSC 的目标之一则是进一步减少客户端需要拥有的实现代码:

Server-only component implementation
        → 留在 Server

Interactive client boundary
        → 才进入 Client JS

所以 RSC 的核心价值不是“SSR 换了个名字”,而是重新定义了 组件实现代码的分发边界。

常见误区

“SSR 页面就是 Server Component 页面”

不对。SSR 描述请求时生成;Server Component 描述执行环境。

“Client Component 就只能 CSR”

不对。Client Component 的初始 UI 仍可被服务端预渲染,随后 hydration。

“有 RSC 就不需要 hydration”

不对。Server Component 自身不需要客户端 hydration,但 Client Component 仍需要客户端 runtime 与接管过程。

“有一个 Client Component,整个 Route 就变成客户端渲染”

不对。一个 Route 可以由大量 Server Components 加少量 Client Boundaries 组成。

最短记忆模型

SSR / SSG / CSR
= 什么时候、在哪里准备页面结果

Server / Client Component
= 组件实现代码需要哪一侧运行时

Hydration
= 已有 HTML 如何接上客户端交互

面试时若只记一句:

先分清“页面何时生成”和“组件在哪里执行”,再讨论 SSR、RSC 与 Hydration。

创建于 2026/3/19 更新于 2026/10/17
Digital Biome
Access

键盘导航

j / k / ↑ / ↓
选择对象
Enter / o
打开选择
/ 或 Ctrl+K
全站搜索
i / f / 1–4
筛选当前列表
g → h / l / p / t / a
首页 / 笔记 / 项目 / 工具 / About
r → 1–9
打开所选对象的关联
u
返回上一页
Esc
关闭浮层 / 取消命令;输入框内清空文本