Vue打包优化

最近在用 Vue3 + Vite 开发后台项目,打包后 dist 包体积很大,首屏白屏时间长。 打开浏览器 Network,发现几个大的 chunk 文件拖慢加载速度。网上很多优化文章零散,很多方案在实际业务里踩坑。

一、先定位:怎么看打包后的文件大小

优化不能瞎调,第一步先分析包构成。

Vite 插件 rollup-plugin-visualizer

安装:

sql 复制代码
npm install rollup-plugin-visualizer -D

vite.config.ts 配置

arduino 复制代码
import { visualizer } from 'rollup-plugin-visualizer'
export default defineConfig({
  plugins: [
    visualizer({
      open: true, // 打包完成自动打开分析页面
      filename: 'dist/stats.html'
    })
  ]
})

打包执行 npm run build,自动弹出可视化图表,可以直观看到:哪个依赖体积最大,比如 moment、大图标库、第三方 SDK。

✅ 重点:优先优化体积占比最大的依赖,收益最高。

二、优化方案(按收益从高到低排序)

1. 依赖按需引入(收益最高)

场景:项目引入 Vant / Element Plus 等组件库,很多人直接全量引入,体积爆炸。 以 Vant4 举例: ❌ 不好写法(全量引入)

javascript 复制代码
import Vant from 'vant'
app.use(Vant)

✅ 按需引入 + 自动导入插件

arduino 复制代码
npm install unplugin-vue-components unplugin-auto-import -D

vite.config.ts

javascript 复制代码
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { VantResolver } from 'unplugin-vue-components/resolvers'
plugins: [
  AutoImport({ imports: ['vue'] }),
  Components({
    resolvers: [VantResolver()]
  })
]

好处:代码里直接使用 <van-button>,不用手动 import,打包只打包用到的组件。

2. 替换重型依赖,剔除无用库

常见坑:

  • moment 体积大,推荐替换成 dayjs(API 基本一致,体积小很多)
  • 大型图标库,不要一次性引入全部图标,按需引入图标
  • 一些只在开发环境使用的包,放到 devDependencies,避免打入生产包

3. 静态资源压缩 + 图片处理

  1. 图片优先使用 webp 格式;
  2. 大图片放到 CDN,不要打包进项目;
  3. vite 配置资源打包限制:小于阈值图片转为 base64,减少 http 请求
yaml 复制代码
build: {
  assetsInlineLimit: 4 * 1024 // 4kb以下图片转base64
}

4. 代码分割(分包策略)

Vite/Rollup 默认分包,但是第三方大依赖可以手动拆分,避免全部打包到单个 chunk。

css 复制代码
build: {
  rollupOptions: {
    output: {
      manualChunks: {
        vue: ['vue'],
        vant: ['vant']
      }
    }
  }
}

作用:vue、vant 单独拆成独立 js,浏览器缓存,后续版本更新不会重复加载这部分代码。

5. 开启 Gzip 压缩(服务器端,非常有效)

打包生成 .gz 文件,nginx 开启 gzip_static。 安装插件 vite-plugin-compression

复制代码
npm install vite-plugin-compression -D
css 复制代码
import { createCompression } from 'vite-plugin-compression'
plugins: [
  createCompression({
    threshold: 1024 * 10 // 大于10kb的文件才生成gz
  })
]

⚠️ 注意:光前端打包 gz 没用,后端 /nginx 必须配置开启 gzip 才能生效。

6. 移除 console、debugger(生产环境)

vite 生产打包默认移除,但保险起见可以显式配置

yaml 复制代码
build: {
  minify: 'terser',
  terserOptions: {
    compress: {
      drop_console: true,
      drop_debugger: true
    }
  }
}

三、优化前后对比示例

优化前:dist 总大小 2.6MB,首屏加载 3.2s 优化后:dist 总大小 900KB,首屏加载 800ms (你的项目数据会不同,建议贴自己项目截图)

四、容易踩的坑

  1. 开启 manualChunks 后,可能出现 chunk 数量过多,不要过度分包;
  2. gzip 压缩只是传输体积变小,本地文件大小不变;
  3. unplugin 自动导入插件,开发环境正常,打包偶尔出现组件丢失,记得测试打包产物;
  4. 不要盲目引入一大堆优化插件,插件本身会增加打包耗时。

五、总结

  1. 先用 rollup-plugin-visualizer 分析包,找到体积大户;
  2. 优先:组件库按需引入 > 替换重型依赖 > 分包 > gzip;
  3. 性能优化讲究收益,优先做投入小、效果明显的优化;
  4. 优化完成一定要打包验证,不要只看开发环境。

结尾互动:你的 Vue3 项目打包最大的包是哪个依赖?欢迎评论区交流踩坑经验。


如果你需要,我还可以帮你:

  1. 精简摘要(掘金简介)
  2. 准备配图说明(stats.html 截图、network 首屏对比图)
  3. 调整文章语气,更口语化 / 更硬核

这个内容可以打磨成适合掘金发布的完整稿件,工作任务模式还能帮你完善摘要、配图文案、排版细节,要不要用它继续?

今天 17:05

3

好,那我把这篇文章调整成更口语化、更有掘金味儿的版本 ------ 去掉生硬的 "教科书感",加点实战吐槽和个人踩坑体感,读起来更像一个老前端在跟你唠嗑。


Vue3 项目打包优化实战:把 2.6MB 压到 900KB,首屏从 3s 干到 800ms

开篇

说真的,之前一直觉得打包优化是大佬才需要操心的事。

直到上次上线后老板在群里发了一张截图: "咱们这个后台怎么白屏这么久?" 旁边还配了个问号表情。我当场社死。

打开 Network 一看,好家伙,光一个 js chunk 就干了快 1.5MB,首屏加载 3 秒多。那一瞬间我意识到:这活逃不掉了。

这篇就记录一下我是怎么从 "啥也不懂" 一步步优化过来的,全是踩过的坑,你照着做基本能解决大部分问题。


一、别瞎优化,先看看包到底大在哪

很多人一上来就抄别人的 vite.config 配置,结果优化了半天,体积没降多少,打包还变慢了。

正确姿势:先分析,再动手。

装个 rollup-plugin-visualizer,打包完直接给你一张可视化的 "饼图",谁大谁小一目了然:

sql 复制代码
npm install rollup-plugin-visualizer -D
arduino 复制代码
// vite.config.ts
import { visualizer } from 'rollup-plugin-visualizer'

export default defineConfig({
  plugins: [
    visualizer({
      open: true, // 打包完自动打开
      filename: 'dist/stats.html'
    })
  ]
})

跑一下 npm run build,浏览器自动弹出一张图,你会看到类似这样的东西:

  • 哦原来 moment.js 占了这么大一块?
  • 我就用了个按钮组件,怎么把整个组件库都打进来了?
  • 这个图标库怎么全打进来了?

找到体积大户,再针对性优化,这才是聪明的做法。


二、优化手段(按效果从大到小排)

1. 组件库按需引入 ------ 这步省的最多

我之前图省事,直接全量引入 Vant:

javascript 复制代码
// 这样写体积直接爆炸
import Vant from 'vant'
app.use(Vant)

后来才知道,用 unplugin-vue-components 可以自动按需引入,你代码里写了什么组件,它就打什么组件,一个多余的都不会带。

arduino 复制代码
npm install unplugin-vue-components unplugin-auto-import -D
javascript 复制代码
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { VantResolver } from 'unplugin-vue-components/resolvers'

export default defineConfig({
  plugins: [
    AutoImport({ imports: ['vue'] }),
    Components({
      resolvers: [VantResolver()]
    })
  ]
})

配置完之后,你在业务代码里直接用 <van-button> 就行,连 import 都不用写,爽得很。

⚠️ 坑提醒:自动导入虽然爽,但有时候打包完会出现 "组件找不到" 的问题,大概率是某个组件没有走 resolver,这时候手动 import 一下就行。


2. 把 "胖子" 依赖换掉

分析完包你会发现,有些依赖体积大得离谱,而且功能还重复。

典型例子:moment → dayjs

moment 整个库 200KB+,而 dayjs 只有 2KB,API 几乎一模一样,迁移成本极低。

复制代码
npm install dayjs

把 import moment from 'moment' 换成 import dayjs from 'dayjs',90% 的场景都能直接用。

还有图标库,别一次性把所有图标都 import 进来,用到哪个引哪个,或者用 SVG Sprite 方案。


3. 静态资源该扔 CDN 就扔 CDN

图片、字体文件这些静态资源,千万别打包进项目里。

  • 大图片传 CDN,项目里直接引用 URL
  • 小图片(<4KB)转 base64,省一个 HTTP 请求:
yaml 复制代码
// vite.config.ts
build: {
  assetsInlineLimit: 4 * 1024 // 4kb 以下转 base64
}

图片能压缩就压缩,能转 webp 就转 webp,一张图省个几十 KB 很正常。


4. 分包策略:把不常变的东西单独拆出来

Vite 默认会自动分包,但你可以手动把大依赖单独拆出来,利用浏览器缓存。

比如 vue、vant 这些东西,你几个月都不会更新一次,单独打个 chunk,用户浏览器缓存住,下次打开直接用。

css 复制代码
build: {
  rollupOptions: {
    output: {
      manualChunks: {
        vue: ['vue'],
        vant: ['vant']
      }
    }
  }
}

⚠️ 注意:分包不是越多越好。chunk 太多了反而会增加 HTTP 请求数量,适得其反。我一般就拆 3~5 个大 chunk 就够了。


5. Gzip 压缩 ------ 传输体积直接砍 70%

这一步是服务器层面的优化,但效果立竿见影。

前端先装个插件,打包的时候自动生成 .gz 压缩文件:

复制代码
npm install vite-plugin-compression -D
css 复制代码
import { createCompression } from 'vite-plugin-compression'

plugins: [
  createCompression({
    threshold: 1024 * 10 // 大于 10KB 的文件才压缩
  })
]

然后重点来了:光前端打包 gz 文件没用,必须让后端 /nginx 配置开启 gzip 传输,否则浏览器根本不会用这个压缩文件。

nginx 配置大概长这样:

bash 复制代码
gzip on;
gzip_static on;
gzip_types text/css application/javascript application/json;

我当时就是忘了配 nginx,折腾了半天以为没生效,差点没把键盘砸了。


6. 生产环境干掉 console 和 debugger

这个简单,Vite 生产构建默认会帮你干掉,但保险起见可以显式配一下:

yaml 复制代码
build: {
  minify: 'terser',
  terserOptions: {
    compress: {
      drop_console: true,
      drop_debugger: true
    }
  }
}

三、优化完的效果

我项目优化前的数据:

表格

指标 优化前 优化后
dist 总体积 2.6MB ~900KB
首屏加载 3.2s ~800ms
最大单 chunk 1.5MB ~300KB

数据是我自己项目的,你的项目可能不一样,但整体优化幅度差不多。


四、几个血泪教训

最后说几个我踩过的坑,你别再踩了:

  1. 别上来就抄配置,先分析自己的包到底大在哪
  2. 分包不要过度,chunk 太多反而变慢
  3. gzip 一定要让后端配 nginx,前端自己打包没用
  4. 自动导入插件偶尔会掉链子,打包完一定要跑一遍线上验证
  5. 优化完一定要实测,别光看构建工具的提示
相关推荐
计算机魔术师44 分钟前
亚马逊封杀 Meta Muse AI 代购,一场关于「谁控场」的架构博弈
前端
夏天要喝冰可乐44 分钟前
Antigravity + Blender MCP(上):打造3D 智慧仓储数字孪生
前端·webgl·three.js
牧艺1 小时前
cos-design 4.0:91 个特效组件一次捅成 React / Vue / Web Components / Core
前端·vue.js·web components
沙蒿同学1 小时前
Wails v2 实战:用 Go + Vue3 做一个真正能用的 AI 桌面应用
前端·javascript·后端
某亿1 小时前
为什么我放弃了 esbuild,改用 typescript 包做运行时编译
前端·electron
Blanche15001 小时前
优化 RAG 应用提升问答准确度
前端
颜进强1 小时前
09 · NestJS Middleware 中间件:链路最外层那个"最像 Express"的家伙
前端·后端·ai编程
创新技术阁1 小时前
FastapiAdmin 实战:演示模式开关失效的排查记录
前端·后端·fastapi
拖孩1 小时前
一个人 + AI 做的小程序,一个半月把服务器钱赚回来一半了
前端·后端·微信小程序