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 设计与实现》

目录
相关文章
|
2月前
|
缓存 JavaScript 前端开发
【Vue面试题七】、SPA (单页面) 首屏加载速度慢怎么解决?
这篇文章探讨了单页面应用(SPA)首屏加载速度慢的问题,并提供了多种解决方案,包括减小入口文件体积、静态资源本地缓存、UI框架按需加载、图片资源压缩、组件重复打包、开启GZip压缩和使用服务端渲染(SSR),以优化资源加载和页面渲染,改善用户体验。
【Vue面试题七】、SPA (单页面) 首屏加载速度慢怎么解决?
|
1月前
|
缓存 前端开发 JavaScript
|
4月前
|
缓存 前端开发 UED
前端优化:首屏加载速度的实践
随着互联网技术的飞速发展,前端网页逐渐取代了传统客户端成为用户获取信息、进行交互的重要渠道,但是网页也有常见的弊端,比如网页首屏加载速度的快慢直接影响着用户体验,那么如何提升网页的首屏加载速度,成为了前端开发者必须面对的问题。本文将从多图片懒加载、避免用户多次点击请求以及骨架屏原理等方面,简单分享一下前端优化首屏加载速度的策略优化。欢迎大家在评论区留言交流。
74 2
前端优化:首屏加载速度的实践
|
2月前
|
资源调度 JavaScript 前端开发
如何大幅减少 Vue.js 中的包大小和加载时间,提升用户体验!
如何大幅减少 Vue.js 中的包大小和加载时间,提升用户体验!
|
5月前
|
缓存 JavaScript 前端开发
Vue项目卡顿慢加载?这些优化技巧告诉你!(一)
Vue项目卡顿慢加载?这些优化技巧告诉你!
668 0
|
5月前
|
缓存 编解码 JavaScript
< 前端性能优化: 资源加载优化 >
众所周知,前端是由HTML、CSS、JS等文件资源共同作用下渲染构建出来的。现今前端项目,大多为单页面应用,单页面应用的优点非常多(点击跳转 SPA单页面讲解),但是也并非没有缺点。由于单页面的原因,项目所需资源都需要在初次加载首屏时被加载,这就造成了首屏加载性能受到影响!对于首屏性能优化,就衍生出了相关需要思考的问题。如何将首屏加载的资源,分段将需要的资源及时加载出来,避免页面内容不显示的同时,又能避免加载多余并非立刻需要使用的资源呢?
< 前端性能优化: 资源加载优化 >
|
前端开发 JavaScript Serverless
前端工程化的前端性能的性能优化方案的渲染层面优化之CSS/JS优化
渲染是一种非常重要的前端性能优化方案,因为它可以在不同的环境中提高网页的响应速度和可接受性。
88 2
|
缓存 JavaScript 前端开发
SPA(单页应用)首屏加载速度慢怎么解决?
SPA(单页应用)首屏加载速度慢怎么解决?
97 0
|
5月前
|
缓存 JavaScript 前端开发
Vue项目卡顿慢加载?这些优化技巧告诉你!(二)
Vue项目卡顿慢加载?这些优化技巧告诉你!(二)
378 0
|
5月前
|
JavaScript 前端开发 Java
【面试题】如何解决 Vue首屏加载过慢出现长时间白屏?
【面试题】如何解决 Vue首屏加载过慢出现长时间白屏?