引言:React 组件模型的范式转移
2020 年 React 团队发布 React Server Components(RSC)RFC,标志着 React 从纯客户端渲染模型向服务端-客户端混合组件架构的根本性演进。RSC 不是对 SSR 的改良,而是一种全新的组件范式——它让组件可以在服务端执行、序列化输出,从而直接访问后端资源,同时保持客户端组件的交互性。
1. RSC 的核心原理
1.1 组件树的边界划分
RSC 引入了一个关键概念:组件边界(Component Boundary)。通过 'use client' 指令,开发者明确标记哪些组件需要在客户端运行,其余组件默认在服务端执行。这种设计使得:
- 服务端组件:直接访问数据库、文件系统、内部服务,零网络开销
- 客户端组件:处理用户交互、浏览器 API 调用、状态管理
- 混合渲染:服务端组件可以渲染客户端组件作为子节点,形成自然的组件树
1.2 序列化协议与 Flight 协议
RSC 输出不是 HTML,而是一种称为 React Server Components Protocol(Flight Protocol) 的紧凑数据格式。该协议将组件树序列化为可流式传输的数据块,支持 Suspense 边界的渐进渲染。与 HTML 不同,Flight 协议保留了组件结构信息,使客户端能够精确地复用已有的 React reconciler 逻辑。
// 服务端组件:直接查询数据库
async function ArticleList() {
const articles = await db.query('SELECT * FROM articles LIMIT 10');
return (
<div className="article-list">
{articles.map(article => (
<ArticleCard key={article.id} article={article} />
))}
</div>
);
}
2. 与 SSR 的本质区别
许多人将 RSC 等同于 SSR,这是一个常见误解。两者的本质区别在于:
| 维度 | SSR | RSC |
|---|---|---|
| 执行时机 | 请求时服务端渲染整个页面 | 构建时/请求时流式渲染组件 |
| 输出格式 | HTML 字符串 | Flight 序列化协议 |
| JavaScript 体积 | 所有组件代码发送到客户端 | 服务端组件代码不发送到客户端 |
| 数据获取 | getServerSideProps 集中获取 | 每个组件自主获取所需数据 |
| 交互性 | hydration 后才能交互 | 服务端组件无需 hydration |
3. Next.js App Router 中的工程实践
3.1 文件约定与目录结构
Next.js 13+ 的 App Router 是 RSC 的首次完整工程实现。在 app/ 目录下,所有组件默认都是 Server Components,除非显式标记 'use client':
app/
├── layout.tsx // Root Layout(Server Component)
├── page.tsx // Home Page(Server Component)
├── blog/
│ ├── page.tsx // Blog List(Server Component)
│ └── [slug]/
│ └── page.tsx // Blog Post(Server Component)
└── components/
├── Header.tsx // Client Component(有交互)
└── LikeButton.tsx // Client Component(有状态)
3.2 数据获取模式变革
RSC 使得 React 数据获取从集中式走向分布式:
// ❌ 旧模式(Pages Router):集中获取
export async function getServerSideProps() {
const [posts, users] = await Promise.all([
fetchPosts(),
fetchUsers()
]);
return { props: { posts, users } };
}
// ✅ 新模式(App Router):分布式获取
async function Posts() {
const posts = await fetchPosts(); // 仅获取所需数据
return <PostList posts={posts} />;
}
async function Users() {
const users = await fetchUsers();
return <UserList users={users} />;
}
export default function Page() {
return <><Posts /><Users /></>;
}
4. 性能优化策略
4.1 零字节服务端组件
RSC 最大的性能优势之一是服务端组件代码为零客户端字节。这意味着一个包含 50KB 数据库查询逻辑的服务端组件,其打包后的 JavaScript 不会被发送到浏览器。对于大型应用,这可以显著减少首屏 JavaScript 体积。
4.2 Streaming 与 Selective Hydration
结合 React Suspense,RSC 支持流式渲染和选择性 hydration。服务端优先渲染关键内容(Above-the-fold),非关键内容以流式方式传输。当用户交互触发时,React 才 hydration 相关组件——这意味着用户可以在页面完全 hydration 前就开始交互。
5. 当前限制与未来展望
RSC 目前存在一些限制:服务端组件不能使用 hooks(useState、useEffect 等),不能访问浏览器 API,且必须与客户端组件形成清晰的边界。未来 React 团队计划通过 React Compiler(React Forget) 进一步优化 memoization,并通过 Server Actions 实现服务端组件与客户端之间的双向通信。
总结
React Server Components 代表了一种范式的转变:从"将所有代码发送到客户端再执行"到"在正确的地方执行正确的代码"。虽然学习曲线存在,但对于追求极致性能的现代 Web 应用,RSC 提供了一种兼顾开发效率与用户体验的架构方案。理解并善用这一特性,是前端工程师技术进阶的必经之路。

发表评论 取消回复