Server Components 不是 SSR!
发布: (2026年2月13日 GMT+8 19:20)
4 分钟阅读
原文: Dev.to
Source: Dev.to
SSR 与 React Server Components 对比
SSR 类比
-
传统 SSR:服务器将整个页面渲染成 HTML 字符串,发送给浏览器,随后客户端下载一个庞大的 JavaScript 包来“水合”页面。即使是静态部分(例如页脚)也会被打进该包,导致资源浪费。
-
SSR 流程
- 请求 – 浏览器请求页面。
- 渲染 – 服务器生成完整的 HTML 字符串。
- 交付 – 浏览器立即显示 HTML。
- 水合 – 客户端下载 JavaScript 并挂载事件监听器。水合完成之前,UI 是不可交互的。
RSC 类比
React Server Components 不会发送 HTML,而是发送 UI 的序列化描述(类似 JSON 的树结构)。客户端只收到渲染所需的内容,繁重的逻辑仍然留在服务器端。
- 零包体积 – 只在 Server Component 中存在的代码永远不会离开服务器,从而保持客户端包体积小。
- 直接数据访问 – Server Component 可以直接查询数据库,省去额外的 API 层。
- 选择性交互 – 只有需要客户端行为的部分会使用
use client标记,成为 Client Component。
示例 Server Component
// 🥩 The Server Component (The Steak)
// No 'use client' here. We are in the kitchen!
import { db } from './vibe-database';
export default async function MusicPlaylist() {
const songs = await db.query('SELECT * FROM bachata_hits'); // Direct DB access!
return (
## Party Mix 🎶
{songs.map(song => (
{song.title} - {song.artist}
{/* Import interactivity only where needed */}
))}
);
}
混合使用 Server 与 Client Component 的指南
use client边界:仅在需要交互的叶子组件上添加use client。如果在顶层添加,它会把整棵树都转成客户端包。- Server Component 中不能使用 Hook:
useState、useEffect等 Hook 在 Server Component 中不可用,尝试使用会导致编译时错误。 - 流式渲染 & Suspense:将异步部分包裹在 “ 中,以实现 UI 的渐进式流式传输,类似 VAR 评审暂停播放但仍保持比赛进行的方式。
功能对比
| 功能 | SSR(传统) | RSC(React Server Components) |
|---|---|---|
| 输出 | 纯 HTML 字符串 | 序列化的 UI 树(类似 JSON) |
| JS 包 | 包含所有内容(体积大) | 服务器专属部分为零 JS |
| 交互性 | 水合后(客户端) | 仅在显式的 Client Component 中 |
| 数据获取 | 通常在页面层面 | 在组件层面,直接在服务器上获取 |
实践建议
- 从 Server Component 开始:把它们当作默认的“基座”。
- 仅在需要时添加 Client Component:对于点击、悬停或本地状态,将相应的叶子节点迁移到 Client Component。
- 把服务器想象成厨房:把重处理(数据获取、渲染)留在厨房,只把“调味料”(交互部分)发送给客户端。这样可以减小包体积,提升低端设备的性能。
通过进一步探索 React Server Components,了解它们对现代 Web 开发的影响,继续保持讨论吧。