🚀为什么你的Vue项目打包后体积比别人大了不止2倍?细节处装大X

1,157 阅读6分钟

Vue项目体积优化

上周和朋友出去吃烧烤,他挠着头说:"同样用 Vue 写后台,人家项目打包完300KB,我这直接 1.2MB,到底哪里出问题了?"

哎嘿,这种小细节就是真露脸的机会了,咱必须人前显圣一下子。

依赖相关:依赖里有脏东西!

1. 按需引入做没做?整包导入真有必要吗?

我记得很多年前第一次用 Element UI 时,我直接在 main.js 里怼了句 import ElementUI from 'element-ui',还美滋滋觉得省事。结果打包完发现光这个库就占了 200KB—— 后来才知道,没做按需引入的话,整个组件库的代码都会被拖进项目,就像你去超市只买瓶水,却扛回了整个货架。

正确操作:用 babel-plugin-component 按需抽取,比如只用到 Button 和 Select,实际打包只会包含这两个组件的代码,体积直接砍到 40KB:

// babel.config.js 配置后
import { Button, Select } from 'element-ui'; // 现在真的只引入需要的部分

Vue 3 同学直接换 Element Plus 更香,人家原生支持 ESM,Webpack 会自动摇树,连配置都省了。

2. 有好多个我在到处跑:同一个库装了三遍

有次排查发现项目同时存在 vue@2.6、vue@3.2 和 vue-template-compiler@2.6,原因是不同插件依赖不同版本。用 npm ls vue 一看,好家伙,依赖树里挂着三个 Vue 实例,相当于项目背着三个版本的代码跑。​

解决办法

  • 跑一遍npm dedupe 合并重复依赖,瞬间能瘦 50KB
  • 提交时一定要锁版本,package-lock.json 就是防止依赖乱跳的「紧箍咒」

补充点

  • 除 npm ls 外,推荐使用可视化工具 npm list --depth=0 或 depcheck 检测未使用的依赖,提升排查效率
  • Vue 3 的 vue@3 与 @vue/compiler-sfc@3 需版本严格对齐,否则可能导致 vue-template-compiler 重复引入
  • 按需引入组件时,若项目同时使用 CSS 预处理器(如 SCSS),需手动引入对应样式(import 'element-ui/lib/theme-chalk/button.css'),避免样式丢失

资源相关:图片和字体在偷吃!

1. 设计稿直接拖进项目?不再犹豫一下了?

之前接手一个后台项目,光登录页的背景图就 1.5MB,打包完发现图片占了整个包的 60%。设计师给的 PNG 没压缩,还带着透明通道,浏览器加载时相当于在下载一张高清照片。

  • 开发时用 Squoosh 把 PNG 转 WebP,体积能缩 70%,肉眼几乎看不出区别

  • 图标别用字体文件!我们团队之前用 iconfont 带着 200 个未使用的图标,换成 SVG sprite 后,体积从 80KB 降到 30KB,还能随意改颜色

// Vite 里加这个插件,图片打包时自动压缩
import imagemin from 'vite-plugin-imagemin'; 
// 配置里加上,gif、png、jpeg 全部压缩一遍


// 怕有新手在看, 提示一句要先安装了再用
npm install vite-plugin-imagemin -D  

2. 来,给他们整个活,基础库咱也用上CDN

早期我总觉得把 Vue 打进包里更保险,直到发现光 Vue 3 就占了 100KB。

后来试了 CDN 方案:在 index.html 里引入

<script src="<https://unpkg.com/vue@3/dist/vue.global.prod.js>"></script>

然后在 Webpack 里配置 externals 排除,打包体积直接少了一个「Vue 大小」。

// webpack.config.js  
module.exports = {  
  externals: {  
    vue: 'Vue',  
    'vue-router': 'VueRouter' // 若使用 Vue Router 也需排除  
  }  
}; 

先别急,使用 CDN 可能存在网络延迟、CDN 服务不可用等问题,最佳实践如下

  • 搭配本地 fallback(如同时提供本地副本,通过 JS 错误捕获切换)
  • 选择更稳定的 CDN(如 jsDelivr、cdnjs,避免单一依赖 unpkg)
  • 并非所有库都适合 CDN(如项目专属库、网络环境差的场景),建议通过 webpack-bundle-analyzer 对比
  • CDN 前后的体积变化和加载速度

代码相关:开发期的东西记得检查检查!

1. 生产环境还留着调试代码?console.log 在拖后腿

有次上线前忘了清日志,项目里几百个 console.log('请求成功') 全被打进包,光这部分就多了 20KB—— 相当于带着一堆没用的文件跑马拉松。更关键的是,Vue 的生产提示没关,v-if 不能和 v-for 一起用(这种毛病还能犯那是给我看哈气了) 这类警告代码也占了 30KB。

必须检查:

  • 用 ESLint 禁止生产环境出现 console 和 debugger

  • Vue 2 记得在 Webpack 里加 Vue.config.productionTip = false,Vue 3 在 Vite 里设置 define: { 'import.meta.env.PROD': true }

2. 所有组件一起加载?首页在背着整个项目跑

之前做一个多页面系统,首页同时加载了报表、大屏组件这些用户可能永远不会点的页面(当然这话不能让产品听到),app.js 直接冲破 800KB。后来改成路由懒加载,用户访问首页时只加载当前组件,其他页面等到点击时再加载,首屏体积瞬间腰斩。

// 不合适:首页加载所有组件

import Home from './Home.vue'; 

import Report from './Report.vue'; 



// 更好的办法:用到时再加载,打包后生成独立文件

const Home = () => import('./Home.vue'); 

const Report = () => import('./Report.vue');

构建相关

1. 压缩开关开了吗?别让代码裸奔

有次新人没开 Webpack 压缩,打包后的 JS 代码全是明文,体积比压缩后大了一倍。Vue CLI 虽然默认开了,但如果你加了奇怪的插件导致冲突,记得手动检查:

// Webpack 必须配置 Terser​

const TerserPlugin = require('terser-webpack-plugin'); ​

plugins: [new TerserPlugin()]

Vite 用户别以为默认压缩 CSS,加上 cssnano 能再瘦 10%。

2. 还在兼容 IE 11?现代浏览器用户不需要老补丁

如果项目面向年轻用户,那就没必要保留着大量 IE 兼容代码,

把 browserslist 改成 last 2 versions 后,polyfill 体积能直接少15%。

实战

实战案例:某中台项目体积优化对比(含第三方库与静态资源)

优化步骤优化前优化后核心操作与降幅
初始打包1.2MB-未做任何优化,包含整包依赖 + 未压缩资源
1. 按需引入 Element1.2MB900KB移除未使用的组件代码,第三方库体积减少 25%
2. 图片压缩 + CDN 分流900KB650KB图片体积压缩 40%+ 排除 Vue 等基础库 100KB,合计减少 250KB
3. 代码拆分 + 懒加载650KB400KB首屏仅加载必要组件,非首屏代码延迟加载,减少 35%
4. 构建层优化(压缩 + 去兼容)400KB280KB开启压缩 + 移除 IE 兼容代码,最终体积再降 30%

实际的体验就是打包时间快了一倍,本地启动、首页加载速度比之前快了不止一点半点,切换页面时几乎没有等待感。

最关键的是用 webpack-bundle-analyzer 生成可视化报告,能清楚看到哪个文件在「增重」,就像给项目做 CT 扫描,哪里有问题一目了然。