React 服务器组件(RSC)向浏览器发送零字节的自身 JavaScript。它们仅在服务器上运行,将 HTML 流式传输到客户端,并可以直接获取数据而无需 API 层。在 Next.js App Router 中,每个组件默认 都是服务器组件。本指南解释心智模型、服务器与客户端之间的边界,以及大规模运行良好的模式。
核心理念
在 RSC 之前,每个 React 组件都向浏览器发送其 JavaScript。获取数据库行、格式化日期并渲染 卡片的组件会将数据库驱动程序、日期库和渲染逻辑都包含在浏览器包中——即使浏览器从不调用数据库。
RSC 改变了这一点:服务器组件只在服务器上运行。其输出被序列化为特殊格式(RSC 负载)并流式 传输到客户端。客户端收到渲染的 HTML 和一个小的调和负载——而不是组件的源代码。
服务器 vs 客户端组件
| 特性 | 服务器组件 | 客户端组件 |
|---|---|---|
| 在服务器运行 | 是 | 是(水合) |
| 在客户端运行 | 否 | 是 |
| 向浏览器发送 JS | 否 | 是 |
| 直接 DB/文件系统访问 | 是 | 否 |
| useState、useEffect | 否 | 是 |
| 事件处理器(onClick 等) | 否 | 是 |
通过在文件顶部添加 "use client" 将组件标记为客户端组件。这是选择加入的边界。 任何导入客户端组件的组件也会成为客户端包的一部分——边界向下传播。
服务器组件中的数据获取
服务器组件可以是 async 函数。你可以直接 await 数据。无需 useEffect、加载状态或 API 路由。组件在获取时挂起,React 在准备好后将结果流式 传输到客户端。用 <Suspense> 包装以在等待时显示回退内容。
Suspense 流式传输模式
Suspense 边界允许 Next.js 分块流式传输 HTML。快速组件立即渲染并发送;慢速组件稍后渲染, 流式传输到已绘制的外壳中。用户看到逐渐完整的页面,而不是空白屏幕后突然的完整绘制。
常见模式
将服务器数据作为 props 传递给客户端组件
服务器组件可以导入客户端组件并向其传递数据。数据被序列化(必须是 JSON 可序列化的——不支持 类实例、函数)并作为 props 传递。
将事件处理器保留在客户端组件中
任何使用 onClick、onChange、useState 或浏览器 API 的组件必须标记为 "use client"。保持这些组件小巧,并将其推向组件树的叶节点以 最小化包大小。
性能影响
采用 RSC 的真实 Next.js 应用在之前客户端获取数据的页面上,JavaScript 包大小减少 30–60%。 由于初始 HTML 包含真实内容而非加载骨架,LCP 得到改善。由于浏览器在加载时需要解析和执行的 JavaScript 更少,INP 也得到改善。