UmiJS 4 打包优化:把 2.6MB 的 umi.js 砍到 860KB 的四步清单
【免费下载链接】umiA framework in react community ✨项目地址: https://gitcode.com/GitHub_Trending/um/umi
生产环境 build 出来的 dist 里躺着一个 2.6MB 的 umi.js,gzip 后传输体积仍高达 840KB,4G 网络下首屏实测要 6.8 秒——这是 umi.js 文件过大最典型的形态。这份 UmiJS 4 打包优化清单按「先定位、再手动拆、后自动拆、最后手动兜底」的顺序推进,每一步都标了适用条件和一句避坑提示,照做即可。
用 ANALYZE 定位 umi.js 的体积大头
别急着改配置,先跑ANALYZE=1 umi build,构建完成后会弹出 chunk 依赖图。UmiJS 4 默认就按路由拆包,页面代码已经在各自的 async chunk 里,所以 umi.js 里剩下的只有三样:框架运行时、被同步 import 的业务代码、以及被顺带拖进来的 node_modules 依赖。在依赖图里看哪个大圆块落在 umi.js chunk 内,体积大头就清楚了。跳过这步直接改配置,方向大概率会错。
用 React.lazy 把大依赖移出主包 📦
这是缩同步主包最直接的杠杆,适用场景:某个组件引用了体积可观的第三方库(图表、富文本编辑器这类)。
import { lazy, Suspense } from 'react'; const Editor = lazy(() => import('./Editor')); // 大库连同依赖链一起拆出去 export default function Page() { return ( <Suspense fallback={<div>loading</div>}> <Editor /> </Suspense> ); }⚠️ 避坑:不是每个组件都值得 lazy 化。一个 5KB 的组件单独拆 chunk,换来的是一次额外网络请求,纯亏。拆分的判断单位应该是「组件 + 它引的大库」,预期 chunk 超过 100KB 再动手。
用 granularChunks 自动分块
大库拆走之后,剩下那些散落的第三方依赖交给框架自动处理,两行配置:
export default { codeSplitting: { jsStrategy: 'granularChunks', }, };granularChunks 人话版就是按粒度自动拆包:把 react、react-dom、history、react-router 归进独立的 framework chunk,超过 160KB 的第三方依赖各自成块,被两个以上异步页面引用的公共模块进 shared chunk。改哪个模块,用户就只重新下载那一块,缓存命中率明显高于整包。看实现源码 packages/preset-umi/src/features/codeSplitting/codeSplitting.ts 会发现一个易踩的细节:它的 lib、shared 分组都是chunks: 'async',只处理异步 chunk——所以它救不了同步依赖,这部分要靠上一步的 lazy 或下一步的 splitChunks。官方思路可对照代码拆分指南。
用 splitChunks 拆同步 node_modules
前两步做完,如果 umi.js 文件过大(仍超 1MB)且大头是同步引入的依赖,就手动兜底:
export default { chainWebpack(memo) { memo.optimization.splitChunks({ chunks: 'all', // 关键:让同步主 chunk 也参与拆分 cacheGroups: { vendors: { name: 'vendors', test: /[\\/]node_modules[\\/]/, priority: -10, // 低优先级,别抢走 framework 分组 }, }, }); }, };拆出的 vendors.js 内容基本恒定,首次加载后长期命中缓存,单独放 CDN 就行;传输体积则交给服务器端 Brotli/Gzip,这决定真实加载耗时。⚠️ 避坑:priority 别高于 framework 分组的 40,否则会把本应在 framework chunk 里的 react 再抢进 vendors,产物里出现两份。
优化前后产物对比
以 40 个页面、首屏 1 条路由的中后台项目为例(4G 约 150KB/s 有效速率):
| 指标 | 优化前 | 优化后 |
|---|---|---|
| umi.js 主包 | 2.6 MB | 860 KB |
| 主包 gzip 传输量 | 840 KB | 260 KB |
| 首屏 JS 总量 | 2.6 MB | 约 1.1 MB(主包 + framework + 首屏路由) |
| 首屏加载耗时 | 6.8 s | 3.2 s |
| 小改动的缓存失效范围 | 整个 umi.js | 仅对应路由 chunk |
下次再遇到 umi.js 膨胀,动作固定为三条:ANALYZE=1 umi build看体积落在哪,大库组件改 lazy,补上 granularChunks 配置。若主包仍不降,再考虑 splitChunks 兜底。
【免费下载链接】umiA framework in react community ✨项目地址: https://gitcode.com/GitHub_Trending/um/umi
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考