性能优化
性能优化
尽管 Vite 默认情况下很快,但随着项目需求的增长,性能问题可能会逐渐显现。本指南旨在帮助你识别和修复常见的性能问题,例如:
- 服务器启动缓慢
- 页面加载缓慢
- 构建速度缓慢
检查你的浏览器设置
某些浏览器扩展可能会干扰请求,并在大型应用中拖慢启动和重新加载的速度,尤其是在使用浏览器开发者工具时。在这种情况下,我们建议创建一个不带扩展的仅开发用浏览器配置,或者在开发 Vite 开发服务器时切换到隐身模式。隐身模式通常也比不带扩展的普通配置更快。
Vite 开发服务器会对预打包的依赖进行硬缓存,并对源代码实现快速的 304 响应。在浏览器开发者工具打开时禁用缓存,可能会对启动速度和整页重新加载速度产生很大影响。请检查使用 Vite 服务器时是否未启用“禁用缓存”选项。
审查配置的 Vite 插件
Vite 内部和官方插件经过优化,在提供与更广泛生态系统兼容性的同时,尽可能减少工作量。例如,代码转换在开发模式下使用正则表达式,在构建时则进行完整解析以确保正确性。
然而,社区插件的性能不在 Vite 的控制范围内,这可能会影响开发体验。以下是使用额外 Vite 插件时需要注意的几个方面:
-
仅在某些情况下使用的大型依赖应通过动态导入来减少 Node.js 的启动时间。示例重构:vite-plugin-react#212 和 vite-plugin-pwa#244。
-
buildStart、config和configResolved钩子不应执行长时间或大量的操作。这些钩子会在开发服务器启动期间被等待,从而延迟你在浏览器中访问网站的时间。 -
resolveId、load和transform钩子可能会导致某些文件比其他文件加载得更慢。虽然有时不可避免,但仍值得检查是否有可优化的地方。例如,在执行完整转换之前,先检查code是否包含特定关键字,或id是否匹配特定扩展名。转换文件所需的时间越长,在浏览器中加载网站时的请求瀑布就越明显。
你可以使用
vite --debug plugin-transform或 vite-plugin-inspect 来检查转换文件所花费的时间。请注意,由于异步操作往往提供不准确的时间,你应该将数字视为粗略估计,但它仍然可以揭示代价较高的操作。
::: tip 性能分析
你可以运行 vite --profile,访问网站,然后在终端中按 p + 回车 来录制一个 .cpuprofile 文件。可以使用像 speedscope 这样的工具来检查分析结果并找出瓶颈。你也可以将分析结果分享给 Vite 团队,以帮助我们识别性能问题。
减少解析操作
解析导入路径在最坏情况下可能是代价很高的操作。例如,Vite 支持通过
resolve.extensions选项“猜测”导入路径,该选项默认为['.mjs', '.js', '.mts', '.ts', '.jsx', '.tsx', '.json']。当你尝试使用
import './Component'导入./Component.jsx时,Vite 将执行以下步骤来解析它:
- 检查
./Component是否存在,没有。- 检查
./Component.mjs是否存在,没有。- 检查
./Component.js是否存在,没有。- 检查
./Component.mts是否存在,没有。- 检查
./Component.ts是否存在,没有。- 检查
./Component.jsx是否存在,有!如上所示,解析一个导入路径总共需要 6 次文件系统检查。你拥有的隐式导入越多,解析路径所花费的时间就越多。
因此,通常最好明确指定导入路径,例如
import './Component.jsx'。你也可以缩小resolve.extensions的列表来减少常规的文件系统检查,但你必须确保它对node_modules中的文件也有效。如果你是插件作者,请确保仅在需要时调用
this.resolve,以减少上述检查次数。 tip TypeScript
如果你使用 TypeScript,请在tsconfig.json的compilerOptions中启用"moduleResolution": "bundler"和"allowImportingTsExtensions": true,以便在代码中直接使用.ts和.tsx扩展名。
:::
避免使用桶文件(Barrel Files)
桶文件是重新导出同一目录下其他文件 API 的文件。例如:
js [src/utils/index.js]
export * from './color.js'
export * from './dom.js'
export * from './slash.js'
当你只导入一个单独的 API,例如 import { slash } from './utils',该桶文件中的所有文件都需要被获取和转换,因为它们可能包含 slash API,并且可能包含初始化时运行的副作用。这意味着你在初始页面加载时加载了比所需更多的文件,从而导致页面加载变慢。
如果可能,你应该避免使用桶文件并直接导入单独的 API,例如 import { slash } from './utils/slash.js'。你可以阅读 issue #8237 了解更多信息。
预热常用文件
Vite 开发服务器只会在浏览器请求时转换文件,这使它能够快速启动并只对使用的文件进行转换。如果它预期某些文件即将被请求,它也可以预先转换这些文件。然而,如果某些文件比其他文件转换时间更长,仍然可能发生请求瀑布。例如:
给定一个导入图,其中左边的文件导入右边的文件:
main.js -> BigComponent.vue -> big-utils.js -> large-data.json
导入关系只能在文件被转换后才知道。如果 BigComponent.vue 需要一些时间转换,那么 big-utils.js 必须等待轮到它,依此类推。即使内置了预转换,这也会导致内部瀑布。
Vite 允许你使用 server.warmup 选项来预热你知道经常使用的文件,例如 big-utils.js。这样,big-utils.js 将被准备好并缓存,以便在请求时立即提供。
你可以通过运行 vite --debug transform 来查找经常使用的文件并检查日志:
bash
vite:transform 28.72ms /@vite/client +1ms
vite:transform 62.95ms /src/components/BigComponent.vue +1ms
vite:transform 102.54ms /src/utils/big-utils.js +1ms
js [vite.config.js]
export default defineConfig({
server: {
warmup: {
clientFiles: [
'./src/components/BigComponent.vue',
'./src/utils/big-utils.js',
],
},
},
})
注意,你只应预热经常使用的文件,以免在启动时使 Vite 开发服务器过载。查看 server.warmup 选项以了解更多信息。
使用 --open 或 server.open 也可以提升性能,因为 Vite 会自动预热你的应用入口点或提供的 URL。
使用更少或原生的工具
随着代码库的增长,保持 Vite 快速的关键在于减少源文件(JS/TS/CSS)的工作量。
减少工作的示例:
- 尽可能使用 CSS 而不是 Sass/Less/Stylus(嵌套可以由 PostCSS / Lightning CSS 处理)
- 不要将 SVG 转换为 UI 框架组件(React、Vue 等)。改为将它们作为字符串或 URL 导入。
使用原生工具的示例:
虽然 Vite 核心基于原生工具,但某些功能默认仍使用非原生工具以提供更好的兼容性和功能集。但对于较大的应用程序,这可能是值得付出成本的。
- 尝试 LightningCSS 的实验性支持
帮助我们改进文档
发现翻译问题或内容错误?请告诉我们。
