译:对 RSC 对 SPA 意味着什么的思考

原文:https://blog.axlight.com/posts/thoughts-on-what-rsc-means-for-spas/
作者:Daishi Kato
译者:Claude 3.5 Sonnet

编者注:RSC 在没有运行时服务器的情况下也能为 SPA 带来好处:1) 通过在构建时渲染和序列化组件来减少 JS 包大小,2) RSC payload 可以按需加载,3) 可以将客户端工作转移到构建过程中。如果有 API 服务器,RSC 还可以:1) 发送已渲染的组件,2) 流式传输数据,3) 无需定义数据格式。

简介

RSC 是 React Server Component 的缩写,但在本文中,我将用 RSC 来指代由两个关键方面组成的更广泛的架构:

  • 核心特性,即序列化和反序列化 React 组件及其他值的能力
  • 基于核心特性的最佳实践,我认为这方面还有待探索

SPA(单页应用)通常可以作为静态文件部署。虽然可能存在独立的服务器,但它通常不会提供 SPA 本身。在这种情况下,SPA 可以有多个页面,但让我们不要争论具体定义。

现在,顾名思义,RSC 通常需要一个运行时服务器,并且有了服务器会更强大。但是,人们经常说我们可以在没有服务器的情况下使用 RSC。

在这篇文章中,我想分享一下我对这个话题的一些随机简短想法。

为了让讨论更有重点,我想把 SSR(服务器端渲染)排除在讨论范围之外。SSR 增加了在运行时服务器或构建时生成 HTML 的能力,这在任何情况下都是一个有价值的附加功能。

RSC 如何立即让 SPA 受益?

即使没有运行时服务器,RSC 也能为 SPA 提供特定的优势。

如果我们没有运行时服务器,RSC 似乎对 SPA 没有好处。然而,如果我们想要减少 JS 包的大小,RSC 的序列化能力对 SPA 是有价值的。如果组件树的某些部分相对静态,我们可以在构建时渲染组件并序列化它们。

RSC payload 是文本,可以作为静态文件提供。我们不需要发送生成 RSC payload 的 JS 代码。例如,markdown 渲染器可以在构建时运行,如果我们不需要在客户端渲染 markdown,我们就不需要在 JS 包中包含 markdown 渲染器。

RSC payload 的静态文件不需要在初始时加载。SPA 可以按需获取它们,就像我们对 JS 包进行懒加载一样。因此,我们基本上可以将一些客户端工作转移到构建过程中。

在这种情况下,SPA 不一定意味着客户端优先。组件树将是服务器优先的,然后我们添加客户端组件。即使应用程序主要由客户端组件构建,我们仍然会有一些服务器组件,因为服务器组件和客户端组件可以在组件树中混合使用。

在我看来,一个缺点是心智模型的转变。现在,我们需要考虑什么应该是服务器组件,什么应该是客户端组件。在纯 SPA 中,我们不需要担心这一点。所以,这是一个权衡。

如果我们为 SPA 有一个 API 服务器,RSC 能做什么?

如果我们的 SPA 有一个 API 服务器,我们就可以使用 RSC。通常,我们会使用 JSON 作为 API 响应,但这可以替换为 RSC payload。

使用 RSC payload 而不是普通 JSON 的好处是:

  • 我们可以发送已渲染的组件和数据:同样,这避免了发送用于渲染组件的 JS 包。
  • 我们可以流式传输数据:数据可以随时间分块发送,让用户可以在数据到达时看到它。
  • 我们不需要定义数据格式。RSC payload 只是在客户端上可渲染的。

所以,基本上它只是另一种线路协议。但是,它是为 React 设计的。我们通常使用 "use server" 指令,它允许与服务器无缝集成并帮助进行类型检查。

还有其他吗?

路由库将在集成 RSC 功能方面发挥重要作用。它们提供面向用户的 API 并隐藏了 RSC 的一些复杂性。它不一定必须是路由器。可以有其他库来隐藏 RSC 的复杂性。只是现在路由器似乎是最常见的库。

结束语

这些只是我对 RSC 如何使 SPA 受益的初步思考。还有更多待发掘的内容,我可能应该通过一些实际的例子重新探讨这个话题。Waku 可以用来创建使用 RSC 的静态站点示例。如果你对这在实践中如何工作感到好奇,我鼓励你尝试一下。