Vite 给人一种又快又慢的感觉,快主要体现在 DevServer 的启动和热更新上,但随之带来的问题是,首屏性能不好以及页面加载时间长的问题。
那为什么 Vite 的首屏性能不是怎么好呢?
就像研究浏览器页面首屏性能,我们会先想到一个问题:从输入 url 到页面显示,这个过程发生了什么?
当我们研究 Vite 首屏性能,就不得不考虑一个问题:从输入 url 到页面显示,Vite 做了什么?
以下是 Vite3.x 的运行流程图:
可以粗略的得出一个结论:
严格来说,Server 启动时间,不算在首屏性能中,不过也值得我们拿出来研究一下。
DevServer 启动前,只做了少量的操作:
可以看出 Server 的启动时间,其实是不随项目的规模变大而显著增长的
注意这里说的是 Vite3.x
在 Vite2.x,Vite 会等待依赖预构建完成,才打印出 Server 端口,这时候才认为 Server 完全启动。
Vite3.x 则直接启动 Server,依赖预构建则异步执行。相当于将构建阶段往后挪了,这就会给人这样一种感觉:启动速度快了,但首屏反而更慢
在浏览器打开页面,会请求 HTML 文件及其需要的静态资源文件
每当请求一个资源文件时,Vite 会对它们进行转换处理,例如:
Vite 并没有在 Server 启动期间进行代码转换,而是在浏览器请求模块时进行编译转换,这就能做到用到哪个模块就编译哪个模块。这也是 Vite Server 启动快的原因,但这同时也会带来更长的首屏时间。
项目规模的变大,对首屏时间的影响?
单个页面需要转换的资源越多,静态资源的转换时间就越长
一般来说,项目规模增大,往往是新增了更多的页面,单个页面使用的模块往往不会随项目规模增长。
如果是这种情况,其实对静态资源处理时间影响不会非常大,因为 Vite 只对使用到的模块进行转换,而其他页面的模块由于没有被使用到,因此也不会被转换。
如何减少获取静态资源的总时间?
依赖预构建的目的有两个:
它的过程主要分为:
从预构建过程可以看出:
因此,项目规模越大,首屏时间就会越慢。当然这也是所有打包工具都会遇到的问题。
Vite 会优先使用本地的预构建产物。只有第一次启动 Vite 的时候,才会进行依赖预构建,第二次启动则会使用上次构建好的依赖。除非项目使用到的依赖 、配置文件发生了变化 ,则需要重新进行预构建。
于是可以分为以下两种情况:
从整个 Vite 的运行流程可以看出,Vite 的启动速度,仅仅是把构建的过程,放到 DevServer 启动之后,构建的时间并没有减少,因此 Vite 也导致了 Vite 的首屏性能不好。
但 Vite 其实已经做了很多的努力了,使用了预构建缓存,运行时的模块转换的缓存,这一些列的措施,是我们在后续开发中的页面性能有了较大的提升。
更多内容可以查看我的专栏:《Vite 设计与实现》