头图
原文 :https://addyosmani.com/blog/r...
翻译:阳羡

本周,React 团队发布了零打包体积的 React 服务端组件(Server Components),旨在用服务端驱动的心理模型实现现代 UX。这与组件的服务器端渲染(SSR)有很大的不同,可能会导致客户端 JavaScript 打包体积大大减少

我对这项工作的方向相当兴奋,虽然它还没有准备用于生产环境中,但非常值得继续关注。我强烈建议大家阅读 RFC 或观看 Dan和Lauren的演讲,了解更多细节。

服务端渲染局限性

今天的客户端 JavaScript 的服务器端渲染可能是次优的。你的组件的 JavaScript 代码在服务器上被渲染成一个 HTML 字符串。这个 HTML 被传递给浏览器,这可能会导致快速的首次内容绘制(First Contentful Paint)或大内容绘制(Largest Contentful Paint)。

然而,JavaScript 代码仍然需要被下载并解析以实现交互性,这通常是通过水合(hydration)步骤实现的。服务器端渲染通常用于初始页面加载,所以在水合(hydration)后您不太可能再看到它被使用。

注意:虽然确实可以利用 SSR 构建一个仅使用服务端渲染(SSR)的 React 应用,完全避免在客户端上水合,但界面上的重交互性往往需要跳出 React。服务端组件启用的混合模型将允许在每个组件的基础上决定是否是 SSR/CSR,或者两者都是。

通过 React 服务端组件,我们的组件可以定期重新获取。当有新的数据时,可以在服务器上运行带有组件的应用程序,从而限制了需要发送给客户端的代码量。

[RFC]: 开发者需要不断地选择使用第三方的包。使用一个包来渲染 markdown 或格式化一个日期,对于我们开发者来说是很方便的,但是它增加了代码的大小,影响了用户的性能。

服务端组件

React 新的服务端组件与服务器端渲染相得益彰,实现了渲染成中间抽象格式,而不需要添加到 JavaScript 打包结果中。这既可以在不损失状态的情况下将服务器树与客户端树合并,又可以扩展到更多组件。

服务端组件不是 SSR 的替代品。当搭配在一起时,它们支持以中间格式快速渲染,然后由服务器端渲染基础架构将其渲染成 HTML,使早期的渲染更加快速。我们对服务端组件生成的客户端组件进行 SSR,类似于 SSR 与其他数据获取机制的使用方式。

然而这一次,JavaScript 的捆绑规模将大大缩小。早期的探索表明,服务端组件对于减少打包体积尤为有效(-18-29%),但一旦进一步的基础设施工作完成,React 团队将对实际的收益有一个更清晰的认识。

[RFC]: 如果我们把上面的例子迁移到服务端组件上,我们就可以为我们的功能使用完全相同的代码,但避免将其发送到客户端--节省了超过 240K 的代码(在未压缩的情况下)。

自动代码分割

通过使用代码分割(code split),只向用户提供他们需要的代码,这被认为是一种最佳实践。这允许你将你的应用程序分解成更小的捆绑包,需要更少的代码发送到客户端。在服务端组件之前,人们会手动使用 React.lazy() 来定义 "拆分点",或者依靠元框架设置的启发式,比如路由/页面来创建新的分块(chunk)。

代码分割的一些挑战是:

  • 在框架(如 Next.js)之外,你经常不得不手动解决这个优化问题,用动态导入代替导入语句。
  • 它可能会延迟应用程序开始加载组件的时间,影响用户体验。

服务端组件引入了自动代码分割,将客户端组件中的所有正常导入视为可能的代码分割点。它们还允许开发人员更早地(在服务器上)选择使用哪个组件,允许客户端在渲染过程中更早地获取它。

服务端组件会取代 Next.js 的 SSR 吗?

不,它们是完全不同的。随着研究和实验的继续,最初采用的服务端组件其实会通过 Next.js 等框架进行实验。

Dan Abramov 对 Next.js SSR 和服务端组件之间的区别已经做了很好的解释:

  • 服务端组件的代码从来不会被传送到客户端。在许多使用 React 的 SSR 实现中,组件代码无论如何都会通过 JavaScript 包发送至客户端。这可能会延迟可交互时间。
  • 服务端组件可以从树的任何地方访问后端。当使用 Next.js 时,你习惯于通过 getServerProps() 来访问后端,它的局限性在于只能在顶层页面工作。某些 npm 组件无法做到这一点。
  • 服务端组件可能会被重新获取,同时在树内保持客户端状态。这是因为主要的传输机制比单纯的 HTML 要丰富得多,允许对服务器渲染的部分(例如搜索结果列表)进行重新请求,而不会破坏里面的状态(例如搜索输入文本、焦点、文本选择)。

服务端组件的一些早期集成工作将通过一个具有以下功能的 webpack 插件来完成:

  • 定位所有客户端组件
  • 创建 ID 之间的映射 => 分块 URLs。
  • 一个 Node.js 加载器,将对客户端组件的导入替换为对其的引用(即不出现在纯服务端组件的打包结果中)。
  • 有些工作需要更深层次的集成(例如与 Routing 等部件的集成),这就是为什么让它与 Next.js 这样的框架一起工作会很有价值。

正如 Dan 所指出的,这项工作的目标之一是让框架变得更好。

深入学习,并欢迎向 React 团队反馈

要了解更多关于这项新功能的信息,请观看 Dan 和 Lauren 的演讲,阅读 RFC,并查看服务端组件的演示来玩转这项新功能。感谢 Sebastian Markbåge、Lauren Tan、Joseph Savona 和 Dan Abramov 在服务端组件上的工作。

The End


豆皮范儿
39 声望5 粉丝

爱编程的字节跳动数据平台前端妹子