跳至内容

性能

虽然 Vite 默认情况下很快,但随着项目需求的增长,性能问题可能会逐渐出现。本指南旨在帮助您识别和解决常见的性能问题,例如

  • 服务器启动缓慢
  • 页面加载缓慢
  • 构建缓慢

检查您的浏览器设置

某些浏览器扩展程序可能会干扰请求,并减慢大型应用程序的启动和重新加载时间,尤其是在使用浏览器开发者工具时。我们建议在使用 Vite 的开发服务器时,创建一个不包含扩展程序的仅用于开发的配置文件,或切换到隐身模式。隐身模式也应该比没有扩展程序的普通配置文件更快。

Vite 开发服务器对预打包的依赖项进行硬缓存,并为源代码实现快速 304 响应。在打开浏览器开发者工具时禁用缓存会对启动和全页面重新加载时间产生重大影响。请确保在使用 Vite 服务器时未启用“禁用缓存”。

审核已配置的 Vite 插件

Vite 的内部和官方插件经过优化,以尽可能减少工作量,同时提供与更广泛生态系统的兼容性。例如,代码转换在开发中使用正则表达式,但在构建中进行完整解析以确保正确性。

但是,社区插件的性能不受 Vite 控制,这可能会影响开发人员体验。在使用其他 Vite 插件时,以下是一些需要注意的事项

  1. 仅在某些情况下使用的较大依赖项应使用动态导入来减少 Node.js 启动时间。示例重构:vite-plugin-react#212vite-plugin-pwa#224.

  2. buildStartconfigconfigResolved 钩子不应该运行长时间且耗时的操作。这些钩子在开发服务器启动期间被等待,这会延迟您在浏览器中访问网站的时间。

  3. resolveIdloadtransform 钩子可能会导致某些文件加载速度比其他文件慢。虽然有时不可避免,但仍然值得检查是否有可能优化的区域。例如,在进行完整转换之前,检查code是否包含特定关键字,或id是否与特定扩展名匹配。

    转换文件所需的时间越长,在浏览器中加载网站时请求瀑布就越明显。

    您可以使用 vite --debug plugin-transformvite-plugin-inspect 检查转换文件所需的时间。请注意,由于异步操作往往提供不准确的计时,因此您应该将这些数字视为粗略估计,但它仍然应该揭示更昂贵的操作。

性能分析

您可以运行 vite --profile,访问网站,并在终端中按 p + enter 记录 .cpuprofile。然后可以使用像 speedscope 这样的工具来检查配置文件并识别瓶颈。您也可以 与 Vite 团队分享配置文件,以帮助我们识别性能问题。

减少解析操作

当解析导入路径时,如果经常遇到最坏情况,这可能是一项昂贵的操作。例如,Vite 支持使用 resolve.extensions 选项“猜测”导入路径,该选项默认为 ['.mjs', '.js', '.mts', '.ts', '.jsx', '.tsx', '.json']

当您尝试使用 import './Component' 导入 ./Component.jsx 时,Vite 将运行以下步骤来解析它

  1. 检查 ./Component 是否存在,不存在。
  2. 检查 ./Component.mjs 是否存在,不存在。
  3. 检查 ./Component.js 是否存在,不存在。
  4. 检查 ./Component.mts 是否存在,不存在。
  5. 检查 ./Component.ts 是否存在,不存在。
  6. 检查 ./Component.jsx 是否存在,存在!

如上所示,解析导入路径需要进行 6 次文件系统检查。您拥有的隐式导入越多,解析路径所需的时间就越长。

因此,通常最好明确您的导入路径,例如 import './Component.jsx'。您还可以缩小 resolve.extensions 的列表以减少一般文件系统检查,但您必须确保它也适用于 node_modules 中的文件。

如果您是插件作者,请确保仅在需要时调用 this.resolve 以减少上述检查次数。

TypeScript

如果您使用的是 TypeScript,请在 tsconfig.jsoncompilerOptions 中启用 "moduleResolution": "bundler""allowImportingTsExtensions": true,以便在代码中直接使用 .ts.tsx 扩展名。

避免使用桶文件

桶文件是重新导出同一目录中其他文件 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'。您可以阅读 问题 #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
export default defineConfig({
  server: {
    warmup: {
      clientFiles: [
        './src/components/BigComponent.vue',
        './src/utils/big-utils.js',
      ],
    },
  },
})

请注意,您应该只预热经常使用的文件,以免在启动时过载 Vite 开发服务器。有关更多信息,请查看 server.warmup 选项。

使用 --openserver.open 也可以提高性能,因为 Vite 将自动预热您的应用程序的入口点或提供的 URL 以打开。

使用较少或本机工具

在不断增长的代码库中保持 Vite 的速度的关键是减少源文件 (JS/TS/CSS) 的工作量。

减少工作量的示例

  • 尽可能使用 CSS 而不是 Sass/Less/Stylus(嵌套可以由 PostCSS 处理)
  • 不要将 SVG 转换为 UI 框架组件(React、Vue 等)。而是将它们作为字符串或 URL 导入。
  • 在使用 @vitejs/plugin-react 时,避免配置 Babel 选项,这样它将在构建期间跳过转换(只使用 esbuild)。

使用本机工具的示例

使用原生工具通常会导致更大的安装包大小,因此在创建新的 Vite 项目时不会默认使用。但对于大型应用程序来说,这可能是值得的。