🍂落页
登 录

React 18 笔记

  • Fiber 架构
  • 新 Suspense 下的 SSR 框架
  • API - react
  • API - react-dom
  • 跳出机制
  • 个人对 React 的理解
  • 发布博客
🍂落页
TALAXY
新 Suspense 下的 SSR 框架
🍂落页
TALAXY

新 Suspense 下的 SSR 框架

新 Suspense 下的 SSR 框架
  • 概要
  • SSR 是什么
  • 当前 SSR 的弊端
  • React 18 带来的改进
  • 参考

原文 写于 2021/6/5 。

概要

SSR 的主要任务:在 JS 代码加载前就能让用户看到页面内容。

React 中 SSR 的执行步骤:

  1. (在服务端)为 整个应用 获取数据。
  2. (在服务端)将 整个应用 渲染成 HTML 并作为响应发送出去。
  3. (在客户端)为 整个应用 加载 JS 代码。
  4. (在客户端)将 JS 代码与 HTML 关联起来(即 hydration)。

但要注意的是 每个步骤都需要等待上一步执行完才可执行 ,因此每个步骤都有可能是整个应用加载慢的原因。

而 React 18 允许你通过 <Suspense> 将 整个应用拆解为不相关联的小单元 ,每个单元都可以单独执行以上的步骤且不会阻塞应用的其它部分。通过这一方式可以让应用显示得更快且更早变得可交互,一些加载慢的内容并不会牵连加载快的内容。这一特性也让 React.lazy 更适合于 SSR 。

SSR 是什么

SSR 可以先在服务端,将 React 组件渲染为 HTML 发送给用户,保证用户可以先看到页面(尽管这样的 HTML 是不可交互的)。而若没有 SSR 技术,在 JS 代码加载前用户通常只会看到白屏(一个空白的 HTML 模版),这对用户是不友好的。

在 JS 代码中,React 也会加载组件树,但并不是为了生成 DOM 节点,而是将所有交互逻辑直接挂载到先前的 HTML 上。这一步被称为 hydration(水合),表示 HTML 就像“吸了水”一样变得可交互了。在此之后,组件可以设置状态、事件也可以进行响应了,等等。

SSR 这一首屏加载的特性对网络较差的用户非常友好,因为无需等到 JS 代码执行就能看到页面。同时也有助于提升搜索引擎排名。

不要将 SSR 和服务端组件搞混了,两者是互补的关系。服务端组件是一个实验性功能,且并不会成为 React 18 初版的一部分。点击 此处 了解更多有关于服务端组件的内容。

当前 SSR 的弊端

上述方法虽然可行,但在许多方面并不是最优的:

  • 在渲染之前你需要获取完所有数据,这意味着如果 API 很慢的话会拖累后续渲染 HTML 的步骤。
  • 在任何 hydrate 前,必须先加载完组件树。这意味着子组件不能单独提前变得可交互。
  • 只有当 hydrate 完全结束后才可变得可交互。这是 React 自身的设计问题。一些组件如果很晚才变得可交互对于用户来说可能是致命的,比如导航栏。

但总的来说,一切弊端归因于前文说的 SSR 执行步骤,因为每一个执行步骤都是阻塞的,且粒度都是整个应用。而 React 18 希望借助 Suspense 将 SSR 的执行粒度从整个应用降低为组件。

React 18 带来的改进

通过 Suspense 可以解锁 React 18 带来的两项 SSR 特性:

  • 在服务端上 流式渲染 HTML 。需搭配使用 renderToPipeableStream 方法。
  • 在客户端上 选择性 hydration 。需在客户端使用 hydrateRoot 方法,并利用 Suspense 将应用拆为几个部分。

流式渲染

浏览器在接收 HTML 数据的过程中,会先将可解析的内容展示出来,React 的流式渲染则利用了这一特性。

可以通过 Suspense 将比较慢的组件拆分出来,React 会在需要时先在 HTML 中展示 fallback 值,等该慢组件加载完后再通过传输 <script> 代码

参考

New Suspense SSR Architecture in React 18, gaearon - GitHub

”渐进式页面渲染“:详解 React Streaming 过程,WangHaoyu - 知乎

TALAXY 落于 2023年12月14日 。