升级webpack5对前端性能指标的影响
背景介绍
目前公司部分前端 SPA 项目升级了 webpack5,在做性能报表的时候发现基于 webpack5 构建的项目在 domInteractive 这个指标上与基于 webpack4 的项目有很大的提升。在业务代码类似的情况下,判断是 webpack5 在哪方面做了默认的优化导致了这一提升。
指标 | webpack4 | webpack5 |
---|---|---|
domLoading(dl) | 347 | 241 |
domInteractive(di) | 893 | 264 |
loadEventEnd(lee) | 925 | 882 |
注:具体性能数据受业务影响会有高低,这里只对比指标之间变化的趋势。
现象:
webpack4 的数据显示从 dl 到 di 的时间相对较长,而 webpack5 的数据为 di 到 lee 的时间较长。
原理分析
di 到 di 的这段时间代表的是浏览器解析 dom 树的时间。在浏览器解析 html 的过程中,dom 中的 script 标签会阻塞 dom 树的解析,由于 spa 项目的 html 结构比较简单,所以这段时间几乎都在 js 的加载解析上,所以在常规的前端性能优化方案中,将 script 标签放置在 body 的最底部是最基本的解决方案。
由此可得 webpack5 是肯定是通过优化 script 标签达到优化 di 的时间的。我们通过代码测试一下,将两个相同脚手架搭建的项目,其中一个项目升级到 webpack5,对比构建产物有什么变化。
script 标签被挪到了 head 标签中,并添加了 defer 属性( 关于 defer 可参考 )
查看了一下相关的资料,确定是 html-webpack-plugin 的升级采取了这一默认举措:
而该版本主要是针对 webpack5 的支持,也算是 webpack5 的相关配套设施的优化吧。
总结
其实对于 spa 的项目来说,di 的优化并没有对整体页面的展示带来多大的性能提升。
我认为这一改动主要影响的 di 这一时间来看,可以让这个时间节点表达的含义更准确,尤其是对于 ssr 的业务,之后可以直接从这个指标判断 html 解析的时间,而不会被加载的 script 标签所干扰。如果所有的 script 标签都加上了 defer 属性,那么可以理解为 di 的时间就是 ssr 页面完全展示的时间,至少从这一点看这次的优化还是存在一些实际应用意义的。
2021.11.03 补充
除了 di 的时间,发现 first-paint 和 first-content-paint 的时间也有比较大的区别。这里先放上两者的区别:
在 html 插件对生成的 script 标签做 defer 处理后,first-paint 可能就不在适合判断内容渲染,而 content-paint 对应的是文字,图片或者非空白 canvas 和 svg,很贴合 spa 的场景,在无 loading 的情况下就等于业务内容展示的时间。