这个项目是使用公司脚手架搭建而成的,本身是基于UMI3进行封装的,所以直接认为是针对UMI3优化是没啥问题的,所以想分享一下自己在尝试优化UMI3构建相关速度的一些思路和做法
电脑配置
- 芯片:Apple M1
- 内存:16GB
前端工具
- node:16.17.0
- npm:8.15.0
- yarn:1.22.11
项目依赖
- @umijs/core:3.5.15
路由体量
routes文件有接近4000行,暂且认为有几百个route吧,懒得查了
差异对比
直接上最终优化数据对比表格,每次对比都会包含有无缓存对比。
| 分支 | Dev Time | HMR Time | Build Time | Build Size | Analyze | 备注 |
|---|---|---|---|---|---|---|
| main | 3.88m | 20.09s | 8.93m | 91.21 MB | - | 无缓存 |
| main | 1.30m | 19.99m | 5.03m | - | - | 有缓存 |
| feature/best-hmr | 1.22m | 4.52s | 3.87m | 40.72 MB | - | 无缓存 |
| feature/best-hmr | 45.52s | 4.54s | 1.90m | - | - | 有缓存 |
!! 该结果在同事的window电脑也跑了,基本无变化,优化的热更新速度基本也保持在4s
尝试的方案
× 尝试 umi3 推荐的mfsu
用不了,各种报错,启动不了。修了第一个bug,还会有第二个第三个,无穷无尽,最后顶不住了直接放弃。
小结
放弃
! 尝试 umi3官方提供的一些思路
我这边直接把所有方法都过了一遍
| 官方方法 | 是否使用 | 效果 |
|---|---|---|
| 配置 nodeModulesTransform 为 { type: 'none' } | 否 | 有一些包必须要transform不然项目无法启动,按照官方方式配置type和exclude,直接报错,放弃了 |
| 查看包结构 | 是 | 必用,没啥好说的 |
| 配置 externals | 否 | 这个项目有些特殊,暂时跳过cdn相关的优化。。。 |
| 减少补丁尺寸 | 否 | 浏览器兼容补丁,尽量还是不要动吧 |
| 调整 splitChunks 策略,减少整体尺寸 | 是 | 效果出类拔萃 |
| 通过 NODE_OPTIONS 设置内存上限 | 否 | 跳过 |
| 调整 SourceMap 生成方式 | 否 | 试了很多帖子的配置方式,综合看下来,官方默认的就挺好,再改本地开发调试就不舒服了 |
| monaco-editor 编辑器打包 | 否 | 项目没用到这个 |
| 替换压缩器为 esbuild | 否 | 开发环境没用,生产有效果 |
| 不压缩 | 否 | 没啥效果 |
所以综合下来,结合ANALYZE优先使用splitChunks的方式解决,分析了一下现有的分包策略,发现已经做了,但是因为参数配置有问题所以导致打包出的体积非常夸张。
放一下代码,具体参数和配置这里就不额外分析了 官方都有
chainWebpack(config) {
config.merge({
optimization: {
splitChunks: {
chunks: 'all',
minSize: 3000,
_ minChunks: 6,
+ minChunks: 2,
+ maxAsyncRequests: 40,
+ maxInitialRequests: 40,
automaticNameDelimiter: '.',
cacheGroups: {
// 省略配置
}
}
}
})
}
结论
splitChunks可行,改动之后Build 相关的 Size 和 Time 都一定程度的提升。
- Dev Time → 3.71m 无变化
- HMR TIme → 21.58s 无变化
- Build TIme → 无缓存6.41m 有缓存3.27m
- Build Size Parsed → 40.27 MB
× 使用speed-measure-webpack-plugin进行分析
本身想着用这个插件,看看plugin和loader的消耗时间,但是这个项目不知道为啥用了之后,构建极慢,几个小时都走不完,几经周折,最后放弃借助该插件分析,后面就自己人肉冲了。
小结
放弃
√ 路由JSON文件优化(不通用,可以忽略)
这个应该算是该项目的专属问题了,可能没有太大的参考意义。这里简单提一下。
就是因为某些业务需求,组内的前端小伙伴把route相关信息搬走了,搬到src文件夹下面了,所以原route的JSON文件就没有人任何作用了,但是一直留着没有删除。
就尝试删除试试,没想到带来意外惊喜。
小结
猜测是,公司脚手架或者umi会默认读取配置文件下JSON文件啥的巴拉巴拉,只要读了肯定会占用一定的内存资源,后面就没仔细研究了。毕竟项目还没有优化好,所以重心优先放到优化上,后面有时间在抽空回来看。
- Dev Time → 3.38m 无变化
- HMR TIme → 11.36s
- Build TIme → -- 不牵扯
- Build Size Parsed → -- 不牵扯
√ 深扒UMI的Webpack Loader配置
研究官方配置,过了一遍他们默认集成的loader,发现官方有两个额外的Loader
- ts-in-node_modules
- js-in-node_modules
已知
- 我们开发环境都是在google浏览器操作
- npm包都是已经编译打包过的,基本没有任何一个包会直接提供未编译的ts和js文件进行使用(万事无绝对)
- 回过头再看配置 nodeModulesTransform 为 { type: 'none' }这个官方推荐优化项
- umi的二次编译是为了补丁相关,常规情况下生产环境才会考虑
所以我们
chainWebpack(config) {
+ if (process.env.NODE_ENV !== 'production') {
+ config.module
+ .rule('js-in-node_modules')
+ .include.clear()
+ // 这里单独处理了一下这个包,因为这个包产出的文件还是包含了一定量的es6语法
+ .add(/node_modules[\\/]@tms[\\/]platform-site-pro-tui-table-render/);
+
+ config.module.rules.delete('ts-in-node_modules');
+ }
}
小结
这里额外放两篇文章,哈哈哈,回复人都是同一个。
构建速度巨量提升,直接看数据
- Dev Time → 无缓存 1.22m 有缓存49.19s
- HMR TIme → 10.36s 一点点变化 可以忽略
- Build TIme → -- 不牵扯
- Build Size Parsed → -- 不牵扯
√ 按需加载router的弊端
一开始看到过这个帖子,后续考虑文件是否都会被重新走一遍,就尝试【注释掉所有路由】【注释掉一部分】【全部放开】,热更新有明显变化就开始研究相关issue
[Build Performance] chunk graph very much slow
文中都写了就不再赘述
小结
HMR速度巨量提升,直接看数据
- Dev Time → 无缓存 1.22m 有缓存49.19s
- HMR TIme → 4.44s 提升一倍
- Build TIme → -- 不牵扯
- Build Size Parsed → -- 不牵扯