Vite 的首屏性能为什么不好?

简介: Vite 的首屏性能为什么不好?

Vite 的运行流程


就像研究浏览器页面首屏性能,我们会先想到一个问题:从输入 url 到页面显示,这个过程发生了什么?

当我们研究 Vite 首屏性能,就不得不考虑一个问题:从输入 url 到页面显示,Vite 做了什么?

以下是 Vite3.x 的运行流程图:


1686398135803.png

  1. 运行 Vite 命令,启动 DevServer,输出端口
  2. 访问页面,页面会访问静态资源和依赖
  • 请求静态资源时,Vite 会对资源进行转换,然后响应请求
  • 请求依赖时,需要等待依赖预构建完成后,DevServer 才会响应请求。
  1. 当页面资源全部加载并执行完成后,显示首屏。

可以粗略的得出一个结论:

  • 总时间 = Vite Server 启动时间 + 首屏时间
  • 首屏时间 =  Max(所有静态资源请求处理时间, 依赖预构建时间)

Vite Server 启动时间


严格来说,Server 启动时间,不算在首屏性能中,不过也值得我们拿出来研究一下。

DevServer 启动前,只做了少量的操作:

  • 标准化用户传入的 config
  • 初始化 DevServer 对象
  • 热更新相关的逻辑

可以看出 Server 的启动时间,其实是不随项目的规模变大而显著增长的

注意这里说的是 Vite3.x

在 Vite2.x,Vite 会等待依赖预构建完成,才打印出 Server 端口,这时候才认为 Server 完全启动。

Vite3.x 则直接启动 Server,依赖预构建则异步执行。相当于将构建阶段往后挪了,这就会给人这样一种感觉:启动速度快了,但首屏反而更慢


静态资源处理时间


在浏览器打开页面,会请求 HTML 文件及其需要的静态资源文件

每当请求一个资源文件时,Vite 会对它们进行转换处理,例如:

  • 给 HTML 注入热更新脚本
  • 将 Vue 文件转换成 JS 代码,让浏览器能够正确运行
  • 将 less 文件,转换成 CSS

Vite 并没有在 Server 启动期间进行代码转换,而是在浏览器请求模块时进行编译转换,这就能做到用到哪个模块就编译哪个模块。这也是 Vite Server 启动快的原因,但这同时也会带来更长的首屏时间


1686398118426.png

项目规模的变大,对首屏时间的影响?

单个页面需要转换的资源越多,静态资源的转换时间就越长

一般来说,项目规模增大,往往是新增了更多的页面,单个页面使用的模块往往不会随项目规模增长

如果是这种情况,其实对静态资源处理时间影响不会非常大,因为 Vite 只对使用到的模块进行转换,而其他页面的模块由于没有被使用到,因此也不会被转换。

如何减少获取静态资源的总时间?

  • 使用 HTTP2。因为浏览器对 HTTP 1 的请求,会有并发上限,达到上限的请求,需要排队。而 HTTP 2 有多路复用的特性,则不会用并发上限的问题
  • 使用缓存。Vite 其实已经内置了,第二次访问相同的资源时,Vite 会返回 304 状态码,使用浏览器缓存。但这个对首屏没有帮助,第一次仍然需要进行模块代码转换。如果需要提升首屏性能,则需要持久化缓存,但这个 Vite 只是有规划,但是仍然没有实现。

依赖预构建时间


依赖预构建的目的有两个:

  • CommonJS 和 UMD 兼容性
  • 提升性能

它的过程主要分为:

  • 依赖扫描/依赖发现阶段
    需要扫描所有项目文件,找到所有项目中使用到的依赖。更多细节可以查看《五千字深度解读 Vite 的依赖扫描》
  • 预构建阶段
    本质就是对项目中用到的依赖,提前进行构建打包,是一次使用 esbuild 的多入口构建,入口为所有项目依赖的入口脚本(各依赖 package.json 中定义的入口文件)。更多细节可以查看《快速理解 Vite 的依赖预构建》


1686398101811.png

从预构建过程可以看出:

  • 依赖扫描的性能,与项目的文件数量有关,项目文件越多,需要扫描的文件就越多,时间就越长
  • 预构建的性能,与项目使用的依赖的数量有关,使用的模块越多,需要构建的模块就越多,时间就越长

因此,项目规模越大,首屏时间就会越慢。当然这也是所有打包工具都会遇到的问题。

Vite 会优先使用本地的预构建产物。只有第一次启动 Vite 的时候,才会进行依赖预构建,第二次启动则会使用上次构建好的依赖。除非项目使用到的依赖 、配置文件发生了变化 ,则需要重新进行预构建。

于是可以分为以下两种情况:

  • 首次执行 Vite,依赖预构建时间 > 所有静态资源请求处理时间。因此我们在开发者工具 Network 中,常常能看到,页面的所有静态资源请求都已经全部响应完成,但是部分依赖仍然在请求状态中。此时性能瓶颈在依赖预构建,直到依赖的请求全部响应,页面才展示。
  • 非首次启动 Vite 时,由于有缓存,不需要依赖预构建,这时候首屏的主要耗时在静态资源的文件转换

1686398084370.png


总结


从整个 Vite 的运行流程可以看出,Vite 的启动速度,仅仅是把构建的过程,放到 DevServer 启动之后,构建的时间并没有减少,因此 Vite 也导致了 Vite 的首屏性能不好。

但 Vite 其实已经做了很多的努力了,使用了预构建缓存,运行时的模块转换的缓存,这一些列的措施,是我们在后续开发中的页面性能有了较大的提升。

如果这篇文章对您有所帮助,可以点赞加收藏👍,您的鼓励是我创作路上的最大的动力。也可以关注我的公众号订阅后续的文章:Candy 的修仙秘籍(点击可跳转)


关联阅读


更多内容可以查看我的专栏:《Vite 设计与实现》

目录
相关文章
|
4月前
|
前端开发 JavaScript UED
前端性能优化:从加载速度到用户体验的技巧大揭秘
在当今互联网时代,用户对于网页加载速度和交互体验的要求越来越高。作为前端开发者,我们应该重视性能优化,通过一系列技巧来提升网页的加载速度、响应速度和用户体验。本文将介绍一些实用的前端性能优化技巧,帮助开发者打造高效、流畅的网页应用。
29 1
|
4月前
|
缓存 JavaScript 前端开发
Vue项目卡顿慢加载?这些优化技巧告诉你!(一)
Vue项目卡顿慢加载?这些优化技巧告诉你!
|
18天前
|
缓存 编解码 JavaScript
< 前端性能优化: 资源加载优化 >
众所周知,前端是由HTML、CSS、JS等文件资源共同作用下渲染构建出来的。现今前端项目,大多为单页面应用,单页面应用的优点非常多(点击跳转 SPA单页面讲解),但是也并非没有缺点。由于单页面的原因,项目所需资源都需要在初次加载首屏时被加载,这就造成了首屏加载性能受到影响!对于首屏性能优化,就衍生出了相关需要思考的问题。如何将首屏加载的资源,分段将需要的资源及时加载出来,避免页面内容不显示的同时,又能避免加载多余并非立刻需要使用的资源呢?
< 前端性能优化: 资源加载优化 >
|
3月前
|
缓存 前端开发 JavaScript
代码如何跑得更快?Vue性能提速指南
代码如何跑得更快?Vue性能提速指南
85 0
代码如何跑得更快?Vue性能提速指南
|
4月前
|
缓存 前端开发 JavaScript
SPA首屏加载速度慢怎么解决
SPA(单页面应用)的首屏加载速度慢可能是由于以下几个方面造成的:
40 0
|
9月前
|
存储 缓存 移动开发
前端首屏性能优化
前端首屏性能优化
|
4月前
|
缓存 前端开发 JavaScript
面试官 : 首屏加载速度慢怎么优化?
面试官 : 首屏加载速度慢怎么优化?
|
9月前
|
缓存 JavaScript 前端开发
SPA(单页应用)首屏加载速度慢怎么解决?
SPA(单页应用)首屏加载速度慢怎么解决?
64 0
|
4月前
|
缓存 JavaScript 前端开发
Vue项目卡顿慢加载?这些优化技巧告诉你!(二)
Vue项目卡顿慢加载?这些优化技巧告诉你!(二)
109 0
|
4月前
|
JavaScript 前端开发 Java
【面试题】如何解决 Vue首屏加载过慢出现长时间白屏?
【面试题】如何解决 Vue首屏加载过慢出现长时间白屏?