React 18 服务器组件深入探讨
React 服务器组件 (RSC) 是一项很有前途的功能,可以对页面加载性能、包大小和我们编写 React 应用程序的方式产生重大影响。此功能在 React 18 中仍处于实验阶段,但值得了解它的工作原理。
服务器和客户端组件分离
React 服务器组件允许服务器和客户端(浏览器)协同工作以呈现您的 React 应用程序。React 元素树中的一些组件由服务器渲染,一些由浏览器渲染。这与服务器端渲染 (SSR) 不同。SSR 模拟了将 React 树渲染成原始 HTML 的环境,但它不区分服务器和客户端组件。
React 团队根据编写组件的文件的扩展名定义了服务器和客户端组件:如果文件以 .server.jsx 结尾,则它包含服务器组件;如果它以 .client.jsx 结尾,则它包含客户端组件。如果两者都不结束,则它包含可用作服务器和客户端组件的组件。
RSC 渲染器的寿命
使用 RSC 的页面的生命总是从服务器开始,以响应 API 调用以呈现 React 组件。然后服务器将根组件元素序列化为 JSON。这里的最终目标是将初始根服务器组件呈现为基本 HTML 标记和客户端组件占位符树。
然后服务器将这个序列化的树发送到浏览器,浏览器可以进行反序列化工作,用实际的客户端组件填充客户端占位符,并呈现最终结果。
RSC 和悬念
悬念在 RSC 中扮演着重要的角色。Suspense 允许您在 React 组件需要尚未准备好的东西(获取数据、延迟导入组件等)时从它们中抛出承诺。这些承诺在悬念边界处被捕获。当从渲染 Suspense 子树中抛出 promise 时,React 会停止渲染该子树,直到 promise 被解析,然后再次尝试。
RSC 有线格式
服务器输出一个简单的格式,每行都有一个 JSON blob,并用 ID 标记。这种格式非常易于流式传输——一旦客户端读取了整行,它就可以解析一段 JSON 并取得一些进展。
使用 RSC 格式
该react-server-dom-webpack
包包含获取 RSC 响应并重建 React 元素树的入口点。当服务器完成加载数据时,它会输出模块引用的行——它定义了对组件的模块引用——以及应该交换到引用所在位置的 React 元素树。
RSC 与从客户端组件获取数据
RSC 是否优于从客户端组件获取数据取决于您在屏幕上呈现的内容。使用 RSC,您可以获得非规范化、“处理过”的数据,这些数据直接映射到您向用户显示的内容。如果渲染需要在瀑布中相互依赖的多个数据提取,那么最好在服务器上进行提取——数据延迟要低得多——而不是在浏览器上进行。
RSC 和 SSR
使用 React 18,可以结合 SSR 和 RSC,因此您可以在服务器上生成 HTML,然后在浏览器中将该 HTML 与 RSC 结合起来。
服务器端渲染 (SSR)
服务器端渲染 (SSR) 是一种技术,其中 React 应用程序在服务器上渲染为静态 HTML 字符串,然后发送到客户端。这可以通过允许在加载和解析所有 JavaScript 之前显示页面来提高性能和 SEO。
import express from 'express';
import React from 'react';
import ReactDOMServer from 'react-dom/server';
import App from './App';
const server = express();
server.get('/', (req, res) => {
const appString = ReactDOMServer.renderToString(<App />);
res.send(`
<!DOCTYPE html>
<html>
<head>
<title>My App</title>
</head>
<body>
<div id="root">${appString}</div>
<script src="/bundle.js"></script>
</body>
</html>
`);
});
server.listen(8080);
在此示例中,App 组件在服务器上呈现为一个字符串,并且该字符串被插入到 HTML 响应中。然后,客户端将这个静态 HTML“水化”成一个完全交互式的 React 应用程序。
React 服务器组件 (RSC)
React 服务器组件 (RSC) 允许服务器和客户端协同工作以呈现 React 应用程序。一些组件呈现在服务器上,而另一些组件呈现在客户端上。这可以通过减少发送到客户端的 JavaScript 数量并允许服务器直接获取和呈现数据来提高性能。
实用建议
- 了解服务器和客户端组件之间的区别: 了解哪些组件由服务器呈现,哪些由客户端呈现对于有效使用 RSC 至关重要。
- 将 Suspense 与 RSC 结合使用: Suspense 允许您处理 React 组件中的承诺,这是 RSC 功能不可或缺的一部分
- 优化性能: RSC 可以显着提高页面加载性能并减小包大小。但是,衡量和监控这些指标以确保您获得预期收益非常重要。
- 考虑权衡: 虽然 RSC 提供了许多好处,但它也有权衡。例如,服务器组件不能使用状态或效果,这会限制它们在某些场景中的使用。
- 在应用程序的非关键部分试验 RSC: 鉴于 RSC 的试验性质,开始在应用程序的非关键部分试验它可能是个好主意。这将使您更好地了解它的工作原理以及如何有效地使用它。
- 将 RSC 与其他 React 功能相结合: RSC 可以与其他 React 功能(如 Suspense 和 Concurrent Mode)相结合,以构建更高效和用户友好的应用程序。
例子。
让我们看一些代码示例来说明 React 服务器组件 (RSC) 的工作原理。
首先,让我们定义一个服务器组件。服务器组件由 .server.js 扩展名标识:
// Message.server.js
import {db} from './db.server';
function Message({id}) {
const message = db.messages.get(id);
return (
<div>
<h1>{message.title}</h1>
<p>{message.body}</p>
</div>
);
}
export default Message;
在此示例中,Message 是一个服务器组件,它根据 id 属性从数据库中获取消息。请注意,我们直接导入服务器模块 (db.server) 并使用它来获取数据。您不能在客户端组件中执行此操作。
接下来,让我们定义一个使用此服务器组件的客户端组件:
// App.client.js
import {useState} from 'react';
import Message from './Message.server';
function App() {
const [selectedId, setSelectedId] = useState(1);
return (
<div>
<button onClick={() => setSelectedId(selectedId + 1)}>
Next
</button>
<Message id={selectedId} />
</div>
);
}
export default App;
在此示例中,App 是一个客户端组件,它维护一个状态 (selectedId) 并使用当前 id 呈现消息服务器组件。单击“下一步”按钮时,selectedId 会递增,导致使用新 ID 再次呈现 Message 组件。
这是一个简单的示例,但它说明了 RSC 背后的关键思想:服务器组件可用于在服务器上获取和呈现数据,而客户端组件在客户端保持交互性。
比较
虽然 SSR 和 RSC 都涉及在服务器上呈现,但它们服务于不同的目的并且有不同的权衡:
SSR 主要关注通过向客户端发送静态 HTML 来提高性能和 SEO。但是,它需要将所有 JavaScript 发送到客户端,这可能会很大并且解析起来很慢。 另一方面,RSC 允许服务器和客户端协作渲染,这可以减少发送到客户端的 JavaScript 量并提高性能。但是,服务器组件不能使用状态或效果,这会限制它们在某些场景中的使用。 总之,SSR 和 RSC 都是用于渲染 React 应用程序的强大技术,每种技术都有自己的优势和权衡。了解这些差异可以帮助您就在项目中使用哪种技术做出更明智的决定。
文章转义来自:dev.to/xakrume/rea…
转载自:https://juejin.cn/post/7236771018609377340