2022 年 6 月 15 日,作者:Andrew Clark、Dan Abramov、Jan Kassens、Joseph Savona、Josh Story、Lauren Tan、Luna Ruan、Mengdi Chen、Rick Hanlon、Robert Zhang、Sathya Gunasekaran、Sebastian Markbåge和 黄玄 。
React 18已经酝酿多年,它为 React 团队带来了宝贵的经验。它的发布是多年研究和探索多种途径的结果。其中一些路径是成功的;更多的是导致新见解的死胡同。我们学到的一个教训是,社区等待新功能却没有深入了解我们正在探索的这些路径是令人沮丧的。
我们通常在任何时候都有许多项目正在进行,从更具实验性的到明确定义的。展望未来,我们希望开始定期分享更多关于我们在这些项目中与社区合作的内容。
为了设定期望,这不是一个有明确时间表的路线图。其中许多项目正在积极研究中,很难确定具体的发布日期。根据我们目前的评估,应该不会在当前的迭代中发布。相反,我们想与您分享我们正在积极思考哪些问题,以及我们迄今为止有所认识的东西。
解读:这个开场白,解答了为什么外界总觉得 React 的更新太慢了。不是 React 团队不干事,是做了很多探索性的工作,有些没啥结果,没有对外说而已,其实忙的很。按照我的理解,像 React 这种前端基础设施,变化太快不见得是一件好事,比如 React-Router 变化快,兼容性也差,当然还有 AngularJS。React 的 API 算是延续性非常好的了,而且相当稳定。
服务器组件 Server Components
我们于 2020 年 12 月宣布了 React 服务器组件 (RSC) 的实验性方案(https://reactjs.org/blog/2020/12/21/data-fetching-with-react-server-components.html)。
从那时起,我们一直在 React 18 支持的部分,并致力于根据实验反馈进行改进。
特别是,我们放弃了使用 fork I/O libraries(例如 react-fetch)的想法,而是采用 async/await 模型以获得更好的兼容性。这在技术上并不会 block RSC 的发布,因为您还可以使用 routers 来获取数据。另一个变化是我们已经不用文件扩展名这种方式,转而支持 注释边界(annotating boundaries)。
我们正在与 Vercel (一个网站托管平台)和 Shopify 合作,统一捆绑程序(unify bundler)对 Webpack 和 Vite 中共享语义(shared semantics)的支持。在发布之前,我们希望确保 RSC 的语义在整个 React 生态系统中是相同的。这是达到稳定的主要障碍。
解读:React Server Component 对我来说是比较陌生的,我平时也没有使用过。看 React 团队的意思,也不希望我们用这种底层特性,而是让 Vercel、Shopify、webpack、 Vite 这些周边生态的库来支持,我们直接用这个库就好了。
资产加载 Asset Loading
目前,脚本、外部样式、字体和图像等资产通常是使用外部系统预加载和加载的。这会使跨新环境(如流、服务器组件等)进行协调变得很棘手。我们正在考虑通过适用于所有 React 环境的 React API 添加 API 以预加载和加载去重的外部资产。
我们也在考虑让这些支持 Suspense,这样您就可以让图像、CSS 和字体在加载之前阻止显示,但不会阻止流式传输和并发渲染。这有助于避免在视觉效果和布局发生变化时出现“爆米花” (popcorning)。
解读:这里解释下“爆米花”这个词,大家开发的时候应该经常看到一个页面在数据加载完成前后,所占的空间大小是差距是非常大的,这就导致页面瞬间有个爆炸的效果。尤其是页面上图片较多的时候。React 团队正在开发一个通用的请求外部资源的 API,来解决这个问题。这块还是挺期待的,希望能早点体验下。
静态服务器渲染优化 Static Server Rendering Optimizations
静态站点生成 (SSG) 和增量静态重新生成 (ISR) 是获得可缓存页面性能的好方法,但我们认为我们可以添加功能来提高动态服务器端渲染 (SSR) 的性能 - 特别是当大多数但不是全部内容是可缓存的。我们正在探索利用编译和静态通道优化服务器渲染的方法。
解读:服务端渲染,我了解的不多,这个应该是一些性能的优化。
React 优化编译器 React Optimizing Compiler
我们在 React Conf 2021 上对 React Forget 进行了 预告useMemo。它是一个编译器,可以自动生成等价的和useCallback调用以最小化重新渲染的成本,同时保留 React 的编程模型。
最近,我们完成了对编译器的重写,使其更加可靠和强大。这种新架构使我们能够分析和记忆更复杂的模式,例如使用局部突变,并开辟了许多新的编译时优化机会,而不仅仅是与缓存挂钩。
我们还在开发一个用于探索编译器许多方面的 Playground 。虽然 Playground 的目标是使编译器的开发更容易,但我们认为它将更容易尝试并为编译器的功能建立直觉。它揭示了它如何在后台工作的各种见解,并在您键入时实时呈现编译器的输出。这将在发布时与编译器一起提供。
解读:从去年底,黄玄介绍了 React Forget ,可以通过编译时优化 React 代码的性能。半年过去了,中间做了很多事情,主要是两件事,一是对编译器本身的开发,另一个是 Playground 的开发。Playground 的意思是游乐场,其实就是可以在线上修改代码并看到运行结果的一个工具。
离屏 Offscreen
今天,如果你想隐藏和显示一个组件,你有两个选择。一种是从树中完全添加或删除它。这种方法的问题在于,每次卸载时 UI 的状态都会丢失,包括存储在 DOM 中的状态,例如滚动位置。
另一种选择是保持组件安装并使用 CSS 直观地切换外观。这会保留 UI 的状态,但会以性能为代价,因为 React 必须在收到新更新时不断渲染隐藏组件及其所有子组件。
Offscreen 引入了第三种选择:在视觉上隐藏 UI,但降低其内容的优先级。这个想法在本质上类似于 content-visibility CSS 属性:当内容被隐藏时,它不需要与 UI 的其余部分保持同步。React 可以推迟渲染工作,直到应用程序的其余部分空闲,或者直到内容再次可见。
Offscreen 只是一个小技巧,他的目的是解锁更高级的功能。与 React 的其他并发特性类似 startTransition,在大多数情况下,您不会直接与 Offscreen API 交互,而是通过一个完善的框架来实现以下模式:
- 即时过渡(Instant transitions):一些路由框架已经预取数据以加速后续导航,例如悬停在链接上时。使用 Offscreen,他们还可以在后台预渲染下一个屏幕。
- 可重用状态(Reusable state):同样,在路线或选项卡之间导航时,您可以使用 Offscreen 来保留前一个屏幕的状态,以便您可以切换回来并从中断处继续。
- 虚拟化列表渲染(Virtualized list rendering):显示大型项目列表时,虚拟化列表框架将预呈现比当前可见的更多行。您可以使用 Offscreen 以低于列表中可见项目的优先级预呈现隐藏行。
- 背景内容(Backgrounded content):我们还在探索一项相关功能,用于在不隐藏背景的情况下降低内容的优先级,例如在显示模式叠加层时。
解读:这个 Offscreen 可是太有用了,通过这个新的 API ,我们可以控制组件的显示和隐藏,但不同于 {isShow &&}和 <div style={{ display: isShow ? 'block':'none' }} 这两种方式,他是类似 CSS 的 content-visibility 的属性,Chromium 85 开始有了 content-visibility属性,这可能是对于提升页面加载性能提升最有效的CSS属性,content-visibility 让用户代理正常情况下跳过元素渲染工作(包括 layout 和 painting ),除非需要的时候进行渲染工作。如果页面有大量离屏(off-screen)的内容,借助 content-visibility 属性可以跳过离屏内容的渲染,加快用户首屏渲染时间,可以做到减少的页面可交互的等待时间。React 后面要提供的这个 API,也不希望开发者直接使用,而是通过使用像 React-Router 这种库来实现,或许不久以后我们就有类似 Vue 里的 Keep-Alive 的功能可用了。
过渡跟踪 Transition Tracing
目前,React 有两个分析工具。Original Profiler显示了分析会话中所有提交的概览。对于每次提交,它还显示所有渲染的组件以及渲染它们所花费的时间。我们还有一个在 React 18 中引入的 Timeline Profiler的 beta 版本,它显示组件何时安排更新以及 React 何时处理这些更新。这两个分析器都可以帮助开发人员识别代码中的性能问题。
我们已经意识到,开发人员并没有发现了解单个缓慢提交或脱离上下文的组件是很有用的。了解导致缓慢提交的真正原因会更有用。并且开发人员希望能够跟踪特定的交互(例如按钮单击、初始加载或页面导航)以观察性能回归并了解交互缓慢的原因以及如何修复它。
我们之前尝试通过创建交互跟踪 API来解决这个问题,但它存在一些基本的设计缺陷,降低了跟踪交互为何缓慢的准确性,有时会导致交互永无止境。由于这些问题,我们最终删除了这个 API 。
我们正在开发一个新版本的交互跟踪 API(暂时称为转换跟踪,因为它是通过 启动的startTransition)来解决这些问题。
解读:React 的性能分析工具很好用,后面还会新增一种时间线的分析工具,Time Profiler ,来分析并发更新时的调度情况。它可以做到当发现某次更新比较缓慢时,可以跟踪这次交互的完整过程,分析性能瓶颈。
新的 React 文档 New React Docs
去年,我们宣布了新的 React 文档网站的 beta 版本。新的学习材料首先教授 Hooks,并有新的图表、插图以及许多交互式示例和挑战。之前我们暂停了这项工作,因为要专注于 React 18 版本的开发,但现在 React 18 已经发布,我们正在积极努力完成和发布新文档。
我们目前正在写一个关于 effects 的详细部分,因为我们听说对于新的和有经验的 React 用户来说,这都是更具挑战性的主题之一。Synchronizing with Effects是该系列中的第一篇文章,接下来几周还会发布更多内容。当我们第一次开始编写有关 effects 的详细部分时,我们已经意识到可以通过向 React 添加新的原始 API 来简化许多常见的 effects 模式。我们在 useEvent RFC中分享了一些初步想法。它目前处于早期研究阶段,我们仍在迭代这个想法。我们感谢社区迄今为止对 RFC 的评论,以及对正在进行的文档重写的反馈和贡献。我们要特别感谢 Harish Kumar(在一家印度金融科技公司工作的印度小哥)提交并审查了对新网站实施的许多改进。
解读:新的 React 文章还是有很多变化,他从 2020年10月开始写的,老文档的问题是原来的文档是以 Class Component 为主线的,但是新的 React 设计思路和发展已经跟之前有了较大的变化,开发者如果还是按照之前的设计思想来理解 React ,就不能快速的获得 React 的真谛,而且目前 Hooks 已经成为 React 最重要的部分,但老的文档里对这部分的介绍优先级比较低,所以新的文档有以下几个变化:
- 以 HOOKS 为主线,串起所有 React 的相关知识,尤其是性能优化部分。
- 介绍 React 新的设计模式,思路和哲学。
- 增强了互动学习的部分,开发者可以在网站上互动的查看示例,和更有意思的 challengesa 帮助你更好的学习。
- 暗夜模式,可以切换黑夜和白天,对于熬夜党很友好。
新的文档到现在已经 1 年多了,很多吐槽一个文档都要写这么久,其实大家细心看这个文档,就会发现是非常考究的,就像一本教科书,极力用通俗的语言把知识点说明白。这也是 Dan 和 Rachel 的强项。