引言: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,这是一个常见误解。两者的本质区别在于:

维度SSRRSC
执行时机请求时服务端渲染整个页面构建时/请求时流式渲染组件
输出格式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 提供了一种兼顾开发效率与用户体验的架构方案。理解并善用这一特性,是前端工程师技术进阶的必经之路。

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论
立即
投稿

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部