大家好,我卡颂。
不知道大家有没有一个感觉:React
新特性的更新速度非常慢,时间通常是以年计。
实际上,在React
漫长的发展过程中,除了很多优秀的特性(比如Hooks
、Suspense
)外,还有很多最终没有落地的想法。
这些想法通常不为开发者所知,这就带来一些「React新特性进展缓慢」的误解。
鉴于此,React官方博客[1]今天发布了一篇文章,介绍了团队当前工作的方向。
本文让我们来了解React
接下来工作的重心,主要包括三方面的内容:
- 底层特性
- 优化相关
- 文档相关
底层特性
进入React18
后,「并发」一词在React
语境下被提及的频率越来越高。
「并发」相关的改动对React
影响也越来越大,甚至影响到日常开发(比如useEffect
在严格模式下开发环境会执行两次)。
作为开发者,我们希望享受「并发」带来的体验提升,但不愿意接受业务代码复杂度提高。
React
团队明白这个道理,所以React
的发展模式主要是:
React团队开发底层特性 与其他开源团队合作开发上层特性
下面我们介绍两个开发中的底层特性。
React Server Components
在20年的一篇官方博客中介绍了React Server Components[2](后文简称为RSC
)。作为底层特性,并不适合开发者直接使用。
React
团队与Vercel
、Shopify
合作,由这些团队接入RSC
,封装到业务框架内部(比如Next.js
),再将框架提供给开发者使用。
这样不仅能加强React
与社区的联系(由类似Vercel
这样的专业公司充当中介),又让React
团队可以专心于React
本身的迭代(而不用分心去开发React
全家桶这样的周边库)。
资源请求
很多外部资源请求(比如脚本、外部样式、字体文件、图片等)都有预加载的需求。
React
团队正在开发「React环境下通用的外部资源请求API」。
用该API
请求的数据,请求过程中可以用Suspense fallback
显示「加载中的效果」,这样可以防止视图「爆爆米花」(popcorning)。
「爆爆米花」这个词真是很形象,他形容「数据加载前后占据的高度不同,从而导致页面尺寸剧烈变化」的现象。
想象页面中有很多「待加载的图片」,随着图片加载,页面被图片不断撑开的样子,就像玉米不断膨胀成爆米花。
优化相关
优化相关进展主要体现在三个方面:
- 编译时
- 运行时
- 分析工具
编译时
黄玄[3]在React Conf 2021[4]介绍了React Forget
,这是一个编译器,用于为「可被优化的React代码」自动加上useMemo
与useCallback
。
该项目一直在不断迭代,最近刚完成重写。同时,编译器的playground
也在同步开发中。
运行时
React
一直没有实现Vue
中的Keep Alive
特性。当前,在React
中控制组件显隐只有两个途径:
mount
/unmout
组件。缺点是:组件卸载后保存在组件中的状态就丢失了,保存在组件对应DOM
中的状态(比如滚动高度)也丢失了- 用
CSS
(比如display: none
)控制组件对应DOM
显隐。这样虽然能保存状态,但却有性能问题 ——React
在运行时还是会遍历隐藏的组件(隐藏的组件还是会render
)
Offscreen API
的出现结合了两者的优点。
遵照开篇提到的「只关注底层特性」原则,开发者最好也不要直接使用Offscreen API
,而是使用「集成了Offscreen的上层框架」(比如路由库)。
插一句题外话,其实Offscreen API
并不是一个全新的API
。在源码内部,他是Suspense
的组成部分之一。
接下来的迭代方向只是将其从源码内部暴露出来。
分析工具
分析组件性能一直是刚需,为此React
团队开发了浏览器分析工具:
随着React18
的到来,会再新增一种时间线分析工具(timeline profiler)用于分析「并发更新时的调度情况」。
但是,他们都没有很好解决以下需求:
- 某一次更新比较缓慢,该怎么分析?
- 某次交互的完整过程(比如一次点击,一次页面导航),该如何分析性能?
当前正在开发一个API
用于分析这些具体情况下的性能问题。
文档相关
React
新文档当前仍处于Beta
版本,内容还不完全。
但React
团队对待新文档的态度,绝对是认真的,有个很有意思的细节:
在总结useEffect
应用场景时,Dan
发现一些常见场景可以用一个新的原生Hook
来应对。
于是,文档写了一半,Dan
又跑去提出了useEvent提案[5]。
虽然当前文档还没完成,但从已公布的内容来看,不管是React
萌新还是老手,都能从新文档中有所收获。
总结
在21年的React
圣诞特辑一起走进React核心团队[6]一文中,作者表达了一个观点:
对于像Hooks
这样的完善特性,能够成为Release
,在其背后还有许许多多特性甚至没到达RFC
阶段。
所有特性都必须等到完全准备就绪为止。在此之前,只能给其他特性让路。
在一个如此重视交付,并且交付的速度越来越快的行业,当你的承诺无法兑现时,这让人非常沮丧。但这并不意味着没有进步:
你有时间思考与计划,有时间实验与学习。即使暂时失败了,也会为成功的特性带来启发。
即使你还没完成年初的预期工作,也要相信挫折和颠覆是常态,而不是例外,无论好坏,即使在React
团队也是如此。
不能因为你没有新的特性产出,就意味着你没有提供价值。
我想,这也是React
团队公布接下来工作方向的一个原因吧。
参考资料
[1]
React官方博客: https://reactjs.org/blog/2022/06/15/react-labs-what-we-have-been-working-on-june-2022.html
[2]
React Server Components: https://reactjs.org/blog/2020/12/21/data-fetching-with-react-server-components.html
[3]
黄玄: https://twitter.com/Huxpro
[4]
React Conf 2021: https://www.youtube.com/watch?v=lGEMwh32soc
[5]
useEvent提案: https://github.com/reactjs/rfcs/pull/220
[6]
一起走进React核心团队: https://react.christmas/2020/24