如何控制Angular项目中的vendor.bundle.js文件大小?
兄弟,我太懂你看到vendor.bundle.js飙到22MB时的崩溃感了!这体积确实离谱,咱们一步步来给它“瘦身”:
第一步:先揪出体积元凶
你得先知道是哪个依赖在撑大这个包,不能瞎优化。Angular自带了分析工具,操作很简单:
- 运行
ng build --prod --stats-json,构建完成后会在dist目录生成stats.json文件 - 装个
webpack-bundle-analyzer(npm install webpack-bundle-analyzer --save-dev),然后运行npx webpack-bundle-analyzer dist/stats.json,就能看到一个可视化的依赖体积占比图,一眼就能找出哪个包是“大胖子”——比如是不是不小心把整个lodash、moment都打包进去了?
第二步:拉满Angular生产构建优化
默认的prod构建其实有优化,但可能你没开全,去angular.json里的configurations.production节点检查这些配置:
- 确保
optimization: true:开启代码压缩和树摇(Tree Shaking),自动删掉没用到的代码 - 确保
buildOptimizer: true:这是Angular专属的优化,能进一步压缩框架相关的代码 - 关于
vendorChunk:如果你的项目里大部分依赖是全局常用的,保持true;如果很多依赖是某个模块单独用的,试试改成false,让依赖和主包合并后更利于树摇(先看第一步的分析结果再决定) outputHashing: 'all':这个主要是缓存优化,但也能辅助压缩效果
第三步:替换大依赖+按需引入
很多时候体积大是因为用了冗余的依赖,或者没按需引入:
- 比如用了moment.js?它默认带所有语言包,直接换成
day.js(体积只有moment的1/10左右),或者手动只引入需要的语言包:import 'moment/locale/zh-cn',再在代码里设置moment.locale('zh-cn') - lodash别直接
import _ from 'lodash',改成按需引入单个方法:import debounce from 'lodash/debounce',或者用lodash-es版本,它天生支持树摇 - UI组件库比如Ant Design Angular、NG-ZORRO这些,别全局引入所有模块,改成按需引入单个组件模块——比如只引入
NzButtonModule,而不是整个NzModule
第四步:给路由模块开懒加载
如果你的项目里有很多不是首屏必须的模块(比如用户中心、设置页面、历史记录这些),改成懒加载,这样这些模块依赖的包就不会跑到vendor里,而是拆分到单独的chunk里,用户用到的时候才加载:
- 路由配置改成这样:
const routes: Routes = [ // 首屏模块直接引入 { path: '', component: HomeComponent }, // 非首屏模块用懒加载 { path: 'user', loadChildren: () => import('./user/user.module').then(m => m.UserModule) } ];
第五步:开启gzip/brotli压缩
就算vendor包还是有点大,让服务器开启gzip或者brotli压缩,浏览器会自动解压,实际传输体积能降到原来的1/3甚至更小:
- 如果是用Nginx部署,直接在配置里开启gzip;如果想在构建阶段就生成压缩文件,可以装
compression-webpack-plugin:- 安装:
npm install compression-webpack-plugin --save-dev - 在
angular.json的build.options.plugins里添加:new CompressionPlugin({ algorithm: 'gzip', test: /\.(js|css|html|svg)$/, threshold: 8192, // 大于8KB的文件才压缩 minRatio: 0.8 // 压缩比小于0.8才保留压缩文件 })
- 安装:
第六步:检查依赖分类
看看package.json里的dependencies和devDependencies,是不是把测试相关的库(比如jasmine、karma、jest)不小心放到dependencies里了?这些测试库应该放在devDependencies里,prod构建时不会打包它们。
内容的提问来源于stack exchange,提问作者Majd Mahajenah
相关产品推荐
相关产品推荐

