Server Components 服务器组件

React Server Components allow you to write UI that can be rendered and optionally cached on the server. In Next.js, the rendering work is further split by route segments to enable streaming and partial rendering, and there are three different server rendering strategies:

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

This page will go through how Server Components work, when you might use them, and the different server rendering strategies.

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

1.Benefits of Server Rendering 服务器渲染的好处

There are a couple of benefits to doing the rendering work on the server, including:

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

  • Data Fetching: Server Components allow you to move data fetching to the server, closer to your data source. This can improve performance by reducing time it takes to fetch data needed for rendering, and the number of requests the client needs to make.
    数据获取:服务器组件允许您将数据获取移至服务器,更靠近您的数据源。这可以通过减少获取渲染所需数据所需的时间以及客户端需要发出的请求数来提高性能。

  • Security: Server Components allow you to keep sensitive data and logic on the server, such as tokens and API keys, without the risk of exposing them to the client.
    安全性:服务器组件允许您将敏感数据和逻辑保存在服务器上,例如令牌和 API 密钥,而无需冒着将它们暴露给客户端的风险。

  • Caching: By rendering on the server, the result can be cached and reused on subsequent requests and across users. This can improve performance and reduce cost by reducing the amount of rendering and data fetching done on each request.
    缓存:通过在服务器上渲染,结果可以在后续请求和跨用户中缓存和重用。这可以通过减少每次请求中完成的渲染和数据获取量来提高性能并降低成本。

  • Bundle Sizes: Server Components allow you to keep large dependencies that previously would impact the client JavaScript bundle size on the server. This is beneficial for users with slower internet or less powerful devices, as the client does not have to download, parse and execute any JavaScript for Server Components.
    捆绑大小:服务器组件允许您将以前会影响客户端 JavaScript 捆绑大小的大型依赖项保留在服务器上。这对网速较慢或设备功能较弱的用户有好处,因为客户端不必下载、解析和执行任何服务器组件的 JavaScript。

  • Initial Page Load and First Contentful Paint (FCP): On the server, we can generate HTML to allow users to view the page immediately, without waiting for the client to download, parse and execute the JavaScript needed to render the page.
    初始页面加载和首次内容绘制 (FCP):在服务器上,我们可以生成 HTML,以便用户可以立即查看页面,而无需等待客户端下载、解析和执行呈现页面所需的 JavaScript。

  • Search Engine Optimization and Social Network Shareability: The rendered HTML can be used by search engine bots to index your pages and social network bots to generate social card previews for your pages.
    搜索引擎优化和社交网络可分享性:呈现的 HTML 可供搜索引擎机器人用来索引您的页面,社交网络机器人用来为您的页面生成社交卡片预览。

  • Streaming: Server Components allow you to split the rendering work into chunks and stream them to the client as they become ready. This allows the user to see parts of the page earlier without having to wait for the entire page to be rendered on the server.
    流式传输:服务器组件允许您将渲染工作拆分为块,并在它们准备就绪时将它们流式传输到客户端。这允许用户更早地看到页面的部分内容,而无需等待整个页面在服务器上渲染。

2.Using Server Components in Next.js 在 Next.js 中使用服务器组件

By default, Next.js uses Server Components. This allows you to automatically implement server rendering with no additional configuration, and you can opt into using Client Components when needed, see Client Components.

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

3.How are Server Components rendered? 服务器组件是如何渲染的?

On the server, Next.js uses React's APIs to orchestrate rendering. The rendering work is split into chunks: by individual route segments and Suspense Boundaries.

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

Each chunk is rendered in two steps:

每个块的渲染分为两个步骤:

React renders Server Components into a special data format called the React Server Component Payload (RSC Payload).

React 将服务器组件渲染成一种称为 React 服务器组件有效负载 (RSC 有效负载) 的特殊数据格式。

Next.js uses the RSC Payload and Client Component JavaScript instructions to render HTML on the server.

Next.js 使用 RSC 有效负载和客户端组件 JavaScript 指令在服务器上渲染 HTML。

Then, on the client:

然后,在客户端:

The HTML is used to immediately show a fast non-interactive preview of the route - this is for the initial page load only.

HTML 用于立即显示快速非交互式路线预览 - 这仅适用于初始页面加载。

The React Server Components Payload is used to reconcile the Client and Server Component trees, and update the DOM.

React 服务器组件负载用于协调客户端和服务器组件树,并更新 DOM。

The JavaScript instructions are used to hydrate Client Components and make the application interactive.

JavaScript 指令用于激活客户端组件并使应用程序具有交互性。

What is the React Server Component Payload (RSC)?
React 服务器组件负载 (RSC) 是什么?

The RSC Payload is a compact binary representation of the rendered React Server Components tree. It's used by React on the client to update the browser's DOM. The RSC Payload contains:
RSC Payload 是已渲染 React Server Components 树的紧凑二进制表示形式。React 在客户端使用它来更新浏览器的 DOM。RSC Payload 包含:

  • The rendered result of Server Components
    Server Components 的渲染结果

  • Placeholders for where Client Components should be rendered and references to their JavaScript files
    Client Components 应渲染的位置的占位符及其 JavaScript 文件的引用

  • Any props passed from a Server Component to a Client Component
    从 Server Component 传递给 Client Component 的任何道具

4.Server Rendering Strategies 服务器渲染策略

There are three subsets of server rendering: Static, Dynamic, and Streaming.

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

a.Static Rendering (Default)

With Static Rendering, routes are rendered at build time, or in the background after data revalidation. The result is cached and can be pushed to a Content Delivery Network (CDN). This optimization allows you to share the result of the rendering work between users and server requests.

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

Static rendering is useful when a route has data that is not personalized to the user and can be known at build time, such as a static blog post or a product page.

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

b.Dynamic Rendering 动态渲染

With Dynamic Rendering, routes are rendered for each user at request time.

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

Dynamic rendering is useful when a route has data that is personalized to the user or has information that can only be known at request time, such as cookies or the URL's search params.

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

Dynamic Routes with Cached Data

具有缓存数据的动态路由

In most websites, routes are not fully static or fully dynamic - it's a spectrum. For example, you can have an e-commerce page that uses cached product data that's revalidated at an interval, but also has uncached, personalized customer data.

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

In Next.js, you can have dynamically rendered routes that have both cached and uncached data. This is because the RSC Payload and data are cached separately. This allows you to opt into dynamic rendering without worrying about the performance impact of fetching all the data at request time.

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

Learn more about the full-route cache and Data Cache.

详细了解全路由缓存和数据缓存。

Ⅰ.Switching to Dynamic Rendering 切换到动态渲染

During rendering, if a dynamic function or uncached data request is discovered, Next.js will switch to dynamically rendering the whole route. This table summarizes how dynamic functions and data caching affect whether a route is statically or dynamically rendered:

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

Dynamic Functions 

Data 

Route 

No

Cached 

Statically Rendered 静态

Yes

Cached 

Dynamically Rendered 动态

No

Not Cached 

Dynamically Rendered 动态

Yes

Not Cached 

Dynamically Rendered 动态

In the table above, for a route to be fully static, all data must be cached. However, you can have a dynamically rendered route that uses both cached and uncached data fetches.

在上面的表格中,要使路由完全静态,必须缓存所有数据。但是,您可以使用缓存和未缓存的数据获取来动态呈现路由。

As a developer, you do not need to choose between static and dynamic rendering as Next.js will automatically choose the best rendering strategy for each route based on the features and APIs used. Instead, you choose when to cache or revalidate specific data, and you may choose to stream parts of your UI.

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

Ⅱ.Dynamic Functions 动态函数

Dynamic functions rely on information that can only be known at request time such as a user's cookies, current requests headers, or the URL's search params. In Next.js, these dynamic functions are:

动态函数依赖于只能在请求时才知道的信息,例如用户的 cookie、当前请求头或 URL 的搜索参数。在 Next.js 中,这些动态函数是:

  • cookies() and headers(): Using these in a Server Component will opt the whole route into dynamic rendering at request time.
    cookies()headers() :在服务器组件中使用这些函数将在请求时将整个路由选择为动态渲染。

  • searchParams: Using the Pages prop will opt the page into dynamic rendering at request time.
    searchParams :使用 Pages 属性将在请求时选择页面进行动态渲染。

Using any of these functions will opt the whole route into dynamic rendering at request time.

使用其中任何一个函数都将在请求时选择整个路由进行动态渲染。

c.Streaming 流媒体

Streaming enables you to progressively render UI from the server. Work is split into chunks and streamed to the client as it becomes ready. This allows the user to see parts of the page immediately, before the entire content has finished rendering.

流式传输使您可以逐步呈现来自服务器的 UI。工作被分成块,并在准备就绪时流式传输到客户端。这允许用户在整个内容完成呈现之前立即看到页面的一部分。

Streaming is built into the Next.js App Router by default. This helps improve both the initial page loading performance, as well as UI that depends on slower data fetches that would block rendering the whole route. For example, reviews on a product page.

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

You can start streaming route segments using loading.js and UI components with React Suspense. See the Loading UI and Streaming section for more information.

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