跳至内容

服务器组件

React 服务器组件允许您编写可以在服务器上渲染和可选缓存的 UI。在 Next.js 中,渲染工作通过路由段进一步拆分,以启用流式传输和部分渲染,并且有三种不同的服务器渲染策略

此页面将介绍服务器组件的工作原理、何时使用它们以及不同的服务器渲染策略。

服务器渲染的优势

在服务器上执行渲染工作有一些好处,包括

  • 数据获取:服务器组件允许您将数据获取移动到服务器,靠近您的数据源。这可以通过减少渲染所需数据获取的时间以及客户端需要发出的请求数量来提高性能。
  • 安全性:服务器组件允许您将敏感数据和逻辑(例如令牌和 API 密钥)保留在服务器上,而无需担心将其暴露给客户端。
  • 缓存:通过在服务器上渲染,结果可以被缓存并在后续请求和用户之间重复使用。这可以通过减少每个请求的渲染和数据获取量来提高性能并降低成本。
  • 性能:服务器组件为您提供了优化性能的额外工具。例如,如果您从完全由客户端组件组成的应用程序开始,将 UI 的非交互式部分移动到服务器组件可以减少所需的客户端 JavaScript 量。这对互联网速度较慢或设备性能较低的用户来说很有帮助,因为浏览器需要下载、解析和执行的客户端 JavaScript 更少。
  • 初始页面加载和首次内容绘制 (FCP):在服务器上,我们可以生成 HTML 以允许用户立即查看页面,而无需等待客户端下载、解析和执行渲染页面所需的 JavaScript。
  • 搜索引擎优化和社交网络共享性:渲染的 HTML 可以被搜索引擎机器人用来索引您的页面,以及社交网络机器人用来为您的页面生成社交卡片预览。
  • 流式传输:服务器组件允许您将渲染工作分成块,并在它们准备就绪时流式传输到客户端。这允许用户更早地看到页面的部分内容,而无需等待整个页面在服务器上渲染完成。

在 Next.js 中使用服务器组件

默认情况下,Next.js 使用服务器组件。这允许您在无需任何额外配置的情况下自动实现服务器渲染,并且您可以在需要时选择使用客户端组件,请参阅客户端组件

服务器组件是如何渲染的?

在服务器上,Next.js 使用 React 的 API 来协调渲染。渲染工作被分成块:通过各个路由段和Suspense 边界

每个块分两步渲染

  1. React 将服务器组件渲染成一种称为**React 服务器组件有效负载 (RSC 有效负载)**的特殊数据格式。
  2. Next.js 使用 RSC 有效负载和客户端组件 JavaScript 指令在服务器上渲染**HTML**。

然后,在客户端

  1. HTML 用于立即显示路由的快速非交互式预览 - 这仅适用于初始页面加载。
  2. React 服务器组件有效负载用于协调客户端和服务器组件树,并更新 DOM。
  3. JavaScript 指令用于水合客户端组件并使应用程序具有交互性。

什么是 React 服务器组件有效负载 (RSC)?

RSC 有效负载是渲染的 React 服务器组件树的紧凑二进制表示。React 在客户端使用它来更新浏览器的 DOM。RSC 有效负载包含

  • 服务器组件的渲染结果
  • 客户端组件应渲染位置的占位符及其 JavaScript 文件的引用
  • 从服务器组件传递到客户端组件的任何 props

服务器渲染策略

服务器渲染有三个子集:静态、动态和流式。

静态渲染(默认)

使用静态渲染,路由在**构建时**或在数据重新验证后后台渲染。结果会被缓存并可以推送到内容分发网络 (CDN)。此优化允许您在用户和服务器请求之间共享渲染工作的结果。

当路由的数据对用户不个性化并且可以在构建时得知时,例如静态博客文章或产品页面,静态渲染非常有用。

动态渲染

使用动态渲染,路由会为每个用户在**请求时**渲染。

当路由的数据对用户个性化或仅在请求时才能知道信息(例如 Cookie 或 URL 的搜索参数)时,动态渲染非常有用。

具有缓存数据的动态路由

在大多数网站中,路由并非完全静态或完全动态 - 它是一个频谱。例如,您可以拥有一个电子商务页面,该页面使用缓存的产品数据(定期重新验证),但也具有未缓存的个性化客户数据。

在 Next.js 中,您可以拥有同时具有缓存和未缓存数据的动态渲染路由。这是因为 RSC 有效负载和数据是分开缓存的。这使您可以选择动态渲染,而无需担心在请求时获取所有数据的性能影响。

了解有关完整路由缓存数据缓存的更多信息。

切换到动态渲染

在渲染过程中,如果发现动态 API或未缓存的数据请求,Next.js 将切换到动态渲染整个路由。此表总结了动态 API 和数据缓存如何影响路由是静态还是动态渲染

动态 API数据路由
已缓存静态渲染
已缓存动态渲染
未缓存动态渲染
未缓存动态渲染

在上表中,要使路由完全静态,所有数据都必须被缓存。但是,您可以拥有一个动态渲染的路由,该路由使用缓存和未缓存的数据提取。

作为开发人员,您无需在静态和动态渲染之间进行选择,因为 Next.js 会根据使用的功能和 API 自动为每个路由选择最佳渲染策略。相反,您可以选择何时缓存重新验证特定数据,并且您可以选择流式传输UI 的部分内容。

动态 API

动态 API 依赖于仅在请求时才能知道的信息(而不是在预渲染期间提前知道)。使用任何这些 API 都会向开发人员发出信号,并会选择在请求时将整个路由切换到动态渲染。这些 API 包括

流式传输

Diagram showing parallelization of route segments during streaming, showing data fetching, rendering, and hydration of individual chunks.

流式传输使您能够逐步从服务器渲染 UI。工作被分成块并随着准备就绪流式传输到客户端。这允许用户立即看到页面的一部分,而无需等待整个内容完成渲染。

Diagram showing partially rendered page on the client, with loading UI for chunks that are being streamed.

流式传输默认内置在 Next.js App Router 中。这有助于提高初始页面加载性能,以及依赖于较慢数据提取的 UI,这些 UI 会阻止渲染整个路由。例如,产品页面上的评论。

您可以使用loading.jsReact Suspense开始流式传输路由段和 UI 组件。有关更多信息,请参阅加载 UI 和流式传输部分。

后续步骤

了解 Next.js 如何缓存数据以及静态渲染的结果。