被diss性能差,Dan连夜优化React新文档

近期在开源圈发生个小插曲。起因是有个用户表示:React新文档在文档结构、美观度、性能等各方面都达到很高的标准。

8dec9bd05edc30bb06269bfa8b82e5c4.png

尤雨溪对Vue新文档与React Beta文档做了测试后表示:在性能这块,Vue新文档更具优势。

be71a4f01430e5e0566f3fd14684fc06.png
左Vue,右React

Dan表示:当前文档还处于Beta版本,现在有更重要的工作要完成,正式版上线前会优化性能。

话虽这么说,Dan应该是通了个宵优化了一把性能:

678224149c50bfc58636e1d87c8912c9.png

本篇文章我们来看看,Dan都做了哪些优化。

优化效果

经过优化后的lightHouse跑分:

b1cb081b4e4cc10c5f1c05c7b3ecf071.png

作为对照,Vue文档的跑分:

f1248bffefbc2a6857f34b741ec241e4.png

两者10次TTI跑分对比:

f6f50fa648afe22fd95f9fb52b8170c0.png

这里的TTI[1](Time to Interactive,即可交互时间),衡量的是「页面变得完全可交互所需时间」,其中「完全可交互」指:

  • 页面展示了「有用信息」(由FCP衡量,FCP指First Contentful Paint)

  • 可见页面中大部分元素完成事件绑定,交互响应的延迟在50ms内

优化措施

优化主要有两个思路:

  • 编译时:减少打包体积

  • 运行时:「非首屏必需」代码延迟加载

编译时优化

之前入口处全量引入了一个工具函数utils,现在将其中方法拆分成不同文件,这样能减少首屏bundle体积:

583608e730443022b75b7b65e5ea8eac.png

再比如:

557bb0f470357422b9453d41b97ec6b1.png

这部分优化让bundle体积减少约一半:

611fe71aca1f7b359645f82b5e5aeb6b.png

其次,当前Next.js(文档使用的框架)没有默认开启「针对现代浏览器编译」。这意味着bundle中会引入更多polyfill,有更多语法转换及帮助函数。

Dan通过配置开启了这个功能:

1def7e7cfb8c21ec11ec953326e7ef37.png

运行时优化

运行时优化的方式主要是:懒加载非必需资源。

新文档中存在很多codesandbox(在线示例),这些示例依赖CodeMirror linter,但这不是首屏必需的。

所以Dan将这部分资源懒加载:

24f6f8fbd50b45a641265fdcf3a4979e.png

除此之外,如果你细心观察会发现,Total Blocking Time指标下降很多:

dbae1d0c541918beab10e987257d80cf.png
左之前,右之后

TBT[2]Total Blocking Time,即总阻塞时间)测量页面「被阻止响应用户输入(例如鼠标点击、屏幕点击或按下键盘)的总时间」(纠正:应该是FCP与TTI之间时间)

一般来说,如果JS执行时间过长,就会影响这个指标。

我们知道,页面加载后前端框架会有首屏渲染的初始化过程。即使是服务端渲染,也会有Hydrate(注水)的过程。

React18Selective Hydration为解决这一问题提供了好方法。

如果你的React18应用是SSR,那么被<Suspense/>包裹的组件部分不会参与首次Hydrate的过程。

也就是说,被<Suspense/>包裹的部分不会影响阻塞时间。

所以,虽然这部分工作很重要,但Dan需要做的,仅仅是把一些「对首屏显示不太重要的组件」包裹在<Suspense/>中。

可以看到,在将一些组件用<Suspense/>包裹前Hydrate作为一个长任务的耗时:

d79e936c6a874d1f484a8cfc8f51a0c0.png

当包裹之后,这个长任务持续时间显著降低,进而降低TBT

8118ef197718c0fc12b500bb86ac00a4.png

总结

这些只是初步的优化结果,后续还有很多优化工作值得去做。比如INP[3](Interaction to Next Paint,与下一次Paint的交互)指标还是偏高:

90242b0186de6bf2339fbae2fab5bcc0.png

Dan坦言:指标偏高的原因可能是因为 —— React本身比较慢。

他对此提出了一些猜想,你可以到这里参与讨论[4]

参考资料

[1]

TTI: https://web.dev/tti/

[2]

TBT: https://web.dev/tbt/

[3]

INP: https://web.dev/inp/

[4]

参与讨论: https://github.com/reactjs/reactjs.org/issues/4691

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值