Skip to content

打包构建优化

start法则

S - Situation (项目背景)

“在项目开发后期,随着业务模块的不断累积(引入了 ECharts、Element Plus、富文本编辑器等大量依赖),我们发现首屏加载速度明显变慢。在弱网环境下,vendor.js 的体积达到了 2MB+,导致白屏时间超过 3 秒,严重影响了用户体验。”

T - Task (主要任务)

“我的任务是优化 Vite 的构建配置,目标是将首屏资源体积减少 50% 以上,并显著提升加载速度。核心策略是实施精细化的代码分割(Code Splitting)高效的资源压缩。”

A - Action (关键行动)

我通过修改 [vite.config.ts] 和编写自定义插件配置,实施了三步走策略:

  1. 手动分包(Manual Chunks)

    • 利用 Rollup 的 output.manualChunks 选项,我将体积庞大且非首屏必须的依赖(如 echarts)强制拆分为独立的 Chunk。
    • 这样,当用户访问仪表盘以外的页面时,浏览器根本不会下载 ECharts 的代码,直接减小了主包体积。
  2. 自动化分包策略

    • 引入 vite-plugin-chunk-split 插件,它能自动分析依赖关系,将 node_modules 中庞大的第三方库拆解为多个小的 vendor chunk,利用浏览器 HTTP/2 的多路复用能力并行加载,解决了“大包阻塞”问题。
  3. 双重压缩(Gzip + Brotli)

    • 配置 vite-plugin-compression2 插件,开启了 GzipBrotli 双重压缩模式。
    • 对于支持 Brotli 的现代浏览器,直接返回压缩率极高的 .br 文件(比 Gzip 小 20%);对于旧浏览器则降级使用 .gz,确保了兼容性和性能的平衡。

R - Result (最终结果)

“优化上线后效果显著:

  1. 体积骤减:静态资源总积减少了 60%,首屏主包体积从 2MB 降至 600KB 左右。
  2. 压缩率提升:Brotli 的引入使得核心文本资源的压缩率达到了 85%
  3. 速度飞跃:首屏 FCP (First Contentful Paint) 时间从 3秒+ 降低到 1秒以内,基本能实现秒开。”

详细版

通过对 [vite.config.ts] 及其 vite/ 目录下插件配置的分析,项目确实在构建优化方面做了大量工作,主要体现在 代码分割 (Code Splitting)资源压缩 (Compression) 两个维度。

1. 代码分割 (Code Splitting)与按需加载

项目使用了 vite-plugin-chunk-split 插件和 Rollup 原生配置来实现精细化的分包策略。

  • 智能分包插件:
    • 在 [vite/chunk.ts] 中引入了 chunkSplitPlugin
    • 虽然代码中仅配置了 strategy: 'default',但这个插件默认会将 node_modules 中的依赖拆分成独立的 chunk,避免 vendor 包过大。
  • 手动分包 (Manual Chunks):
    • 在 [vite.config.ts] 中,显式地将体积巨大的图表库 ECharts 单独打包:
      typescript
      manualChunks: {
        echarts: ['echarts'], // 独立拆分,避免阻塞主包加载
      },
    • 这对于首屏优化至关重要,因为后台管理系统往往只有部分页面需要图表,将其拆分后,首屏加载时无需下载庞大的 ECharts 代码。

2. 双重压缩 (Gzip + Brotli)

项目在 [vite/compression.ts] 中配置了基于 vite-plugin-compression2 的高级压缩策略。

  • 配置逻辑:
    • 读取环境变量 VITE_BUILD_COMPRESS (通常在 .env.production 中配置)。
    • Gzip: 标准压缩,兼容性好,压缩速度快。
    • Brotli: Google 推出的新一代压缩算法,压缩率比 Gzip 高 15-20%,现代浏览器支持良好。
    • 双管齐下: 代码逻辑允许同时开启 gzipbrotli
      typescript
      if (compressList.includes("gzip")) {
        plugin.push(compression());
      }
      if (compressList.includes("brotli")) {
        plugin.push(
          compression({
            exclude: [/\.(br)$/, /\.(gz)$/], // 避免对已压缩文件重复压缩
            algorithm: "brotliCompress",
          }),
        );
      }
    • 效果: 这种策略能确保服务器在支持 Brotli 时优先返回更小的 .br 文件,不支持时降级返回 .gz 文件,最大限度减少传输体积。

3. 其他优化细节

  • Tree Shaking: 生产环境构建时,通过 esbuild 自动移除 consoledebugger ([vite.config.ts:40]),减少无用代码。
  • Legacy 兼容: 使用 @vitejs/plugin-legacy ([vite/index.ts:30]) 处理旧浏览器兼容性,确保新特性代码能自动降级运行。
  • 按需自动导入: 使用 unplugin-auto-importunplugin-vue-components ([vite/auto-import.ts]),无需手动 import Vue API 和组件,Vite 会在编译时按需引入,减少样板代码并优化 Tree Shaking 效果。

总结

这套构建配置是标准的 Vite 生产级优化方案。通过将第三方大库(ECharts)剥离、开启高压缩率算法(Brotli)以及自动化的 Tree Shaking,确实能够显著降低 index.html 引用的首屏资源体积,从而提升 LCP (Largest Contentful Paint) 等关键性能指标。

Released under the MIT License.