跳至内容

性能

虽然 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 扩展名。

避免 Barrel 文件

Barrel 文件是重新导出同一目录中其他文件的 API 的文件。例如:

src/utils/index.js
js
export * from './color.js'
export * from './dom.js'
export * from './slash.js'

当您只导入一个单独的 API 时,例如 import { slash } from './utils',该 barrel 文件中的所有文件都需要被获取和转换,因为它们可能包含 slash API,也可能包含在初始化时运行的副作用。这意味着您在初始页面加载时加载的文件比所需的更多,从而导致页面加载速度变慢。

如果可能,您应该避免 barrel 文件并直接导入单个 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 就必须等待轮到它,以此类推。即使内置了预转换,也会导致内部瀑布效应。

只有在文件被转换后才能知道导入关系。如果 BigComponent.vue 需要一些时间来转换,则 big-utils.js 必须等待轮到它,依此类推。即使内置了预转换,这也会导致内部瀑布流。

Vite 允许您预热您知道经常使用的文件,例如 big-utils.js,使用 server.warmup 选项。这样,big-utils.js 将准备好并缓存,以便在请求时立即提供。

您可以通过运行 vite --debug transform 并检查日志来找到经常使用的文件:
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
bash
js
export default defineConfig({
  server: {
    warmup: {
      clientFiles: [
        './src/components/BigComponent.vue',
        './src/utils/big-utils.js',
      ],
    },
  },
})

vite.config.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 项目时它不是默认设置。但对于较大的应用程序来说,这可能是值得的。
  • 使用 Rolldown 代替 Rollup 和 esbuild,以获得更快的构建速度以及开发和构建之间更一致的体验。
  • 尝试对 LightningCSS 的实验性支持。

下一页Rolldown