相信很多人都有遇到这个问题,为什么 umi 打包完的产物这么大啊?首屏打开时间也太长了吧?特别是用 umi 开发移动端的同学,我们暂且认为首屏开启时间在 3s 内作为合格,5s 内勉强能接受。因为我们去年一年使用 umi 作为移动端的开发,是借助 cordova 将构建产物直接写在本地,所以包的大小对于我们的项目影响较小。但是今年开始有不少的同学将产物以 H5 的形式对外发布,或者以链接的形式,在其他应用中使用 webview 加载出来。于是包大小,首屏打开时间,就成为了我们项目的一个交互指标。
这里我用一个被用户投诉的项目来做演示说明。当然只会展示产物信息,不会涉及任何用户的敏感信息。
这里我们先看一下优化后的结果(同一个电脑同一个网络环境中)。
比对项目 | 原始数据 | 优化后的数据 |
dist 大小 | 8.7MB | 4.5MB |
Fast 3G | 20s | 16.94s |
Online | 4.3s | 503ms |
默认打包
使用 umi 执行打包,不增加任何修改和配置的情况下,所有的 js 代码会被编译到 umi.js 文件中。
umi build
dist 8.7MB 编译时间 21.02s
包名 | Stat Size | Parsed Size | Gzip Size |
all | 6.77MB | 2.75MB | 905.54KB |
umi.js | 6.77MB | 2.75MB | 905.54KB |
增加按需加载
觉得都打到一个文件 umi.js 里面文件太大的话,可以考虑在 config/config 中添加按需加载配置。
export default { dynamicImport: { }, };
页面切换的时候,会有一个默认的 loading ,觉得不是很好看,自己可以修改一下。
export default { dynamicImport: { // @ 默认指到 src 目录 loading: '@/pages/Loading/index', }, };
dist 18.7MB 编译时间 33.68s
包名 | Stat Size | Parsed Size | Gzip Size |
all | 39.16MB | 10.76MB | 3.05MB |
umijs.js | 3.29MB | 1.44MB | 454.97KB |
添加完按需加载,每次在切换页面的时候,都会先走一个 loading 页面,看惯了原生应用的甲方说,不能接受。
这里可以很明显的发现开启按需加载之后,产物包变大了很多,这个可以通过调整 splitChunks 策略,减少整体尺寸。接下来会提到 splitChunks 相关的配置,因此这里没有单独说明。
包分析
首先我们去掉刚刚添加的按需加载配置。
export default { - dynamicImport: { - // @ 默认指到 src 目录 - loading: '@/pages/Loading/index', - }, };
查看产物包的结构
使用 ANALYZE=1 环境变量来查看 build 之后的产物包结构。注意环境变量的使用,mac 上可以直接使用,window 上需要使用 set ,因此在项目中,我们一般是通过安装 cross-env 来抹去平台差异。
{ "scripts": { "build": "cross-env ANALYZE=1 umi build", }, }
编译执行完成之后,你可以查看 http://127.0.0.1:8888
包分析页面。可以看到大致如下图所示的页面。
可能第一次看这个页面,不是很明白什么意思,你可以简单的理解,页面上面积越大的库,就是包大小越大的。比如,现在所有的文件都在 umi.js 文件中,然后占体积最大的是 node_modules,其中体积最大的moment,其次是 @antv/f2,于是我们得到了下面的表格。
包名 | Stat Size | Parsed Size | Gzip Size |
umi.js | 6.77MB | 2.75MB | 905.54KB |
monent | 659.12KB | 367/65KB | 77.78KB |
@antv/f2 | 526.87KB | 221.55KB | 60.51KB |
@alitajs/dform | 357.68KB | 102.51KB | 20.44KB |
src | 1.59MB | 811.24KB | 221.41KB |
查看真实请求耗时数据
一般我将项目编译到 dist 目录之后,都会习惯性的用本地服务查看一次。
arn global add serve cd dist serve Local: http://localhost:5000
这是我所知道的启动一个本地容器最简单的方式了。通过访问 http://localhost:5000
就能访问到我们的项目,而且表现更加接近于真实生产环境。
在网络很快的情况下,我们很难体验到方案修改的差异,所以我们使用 3G 网络模拟一下对网站的请求,总耗时大约在 20s 左右。
通过上述分析,我们发现,下载一个大的文件会比较耗时,所以我们先想办法减小 umi.js 的大小。