3、包体积优化(下):分包加载策略(主包/分包)、独立分包与预加载、分包体积监控
好,咱们接着聊包体积优化。上一节我把代码层面的压缩、图片优化、无用代码清理都讲了一遍。这一节,咱们要啃的是一块硬骨头——分包加载。
说实话,我早期做小程序的时候,最头疼的就是那个2MB的主包限制。那时候功能一多,动不动就超限,每次提审都提心吊胆。后来我学乖了——分包才是根治包体积问题的终极方案。
主包与分包:核心逻辑
先搞清楚一个概念:小程序启动时,只会下载主包。主包里放什么?放那些必须第一时间展示的页面和公共资源。比如首页、登录页、核心的tabBar页面,还有全局通用的组件、工具库。
那分包呢?分包就是那些用户不一定马上用到的功能模块。比如商品详情页、订单列表、个人设置页。这些页面可以拆到不同的分包里,用户访问时才下载。
我个人的习惯是:主包控制在1.2MB以内,留出余量给后续迭代。分包每个控制在500KB左右,别太大,否则加载体验会变差。
来看一个典型的分包配置:
// app.json
{
"pages": [
"pages/index/index",
"pages/login/login",
"pages/mine/mine"
],
"subPackages": [
{
"root": "packageA",
"pages": [
"pages/goods-detail/goods-detail",
"pages/order/order"
]
},
{
"root": "packageB",
"pages": [
"pages/setting/setting",
"pages/feedback/feedback"
]
}
]
}
这里要注意:pages数组里的页面属于主包,subPackages里的页面属于分包。分包之间不能互相引用代码,但分包可以引用主包里的公共模块。
独立分包:让某些页面秒开
分包虽然好,但有个问题:用户访问分包页面时,还是需要先下载主包。如果主包比较大,用户等得就久。
这时候独立分包就派上用场了。独立分包可以不依赖主包,单独下载、单独运行。你想想看,像活动页、广告落地页这种场景,用户从外部链接直接跳进来,如果还要先下载主包,体验就很差。
配置独立分包很简单,加一个 "independent": true 就行:
{
"root": "packageC",
"pages": [
"pages/activity/activity"
],
"independent": true
}
嗯,这里有个细节:独立分包不能引用主包的任何代码。所以如果你的独立分包页面需要用到公共组件,要么把组件复制一份到分包里,要么用纯原生写法。我个人建议尽量保持独立分包轻量,只放一个页面和它独有的资源。
预加载:让用户感觉不到加载
分包解决了体积问题,但带来了新的问题——加载延迟。用户点击某个按钮,才去下载分包,中间会有几百毫秒甚至几秒的等待。怎么优化?
答案是预加载。说白了,就是在用户可能访问某个分包之前,提前把分包下载下来。
配置方式是在 app.json 里加 preloadRule:
{
"preloadRule": {
"pages/index/index": {
"network": "wifi",
"packages": ["packageA"]
}
}
}
这段配置的意思是:当用户进入首页时,如果当前网络是WiFi,就提前下载 packageA 分包。这样用户点击商品详情时,分包已经下载好了,直接打开,几乎没有延迟。
我一般会在首页和tabBar页面做预加载。因为这些页面用户停留时间长,有足够的时间去下载后续分包。而且我习惯加上 "network": "wifi" 限制,避免在移动网络下浪费用户流量。
- 首页 → 预加载商品列表分包(用户大概率会点)
- 商品列表页 → 预加载商品详情分包(用户大概率会看)
- 登录页 → 预加载个人中心分包(登录后大概率会去)
分包体积监控:别让体积悄悄涨回去
分包做完了,是不是就万事大吉了?不是。我见过太多团队,优化完包体积,过两个月又涨回去了。为什么?因为新需求不断加,代码不断堆,没人盯着体积。
所以,分包体积监控必须落地。我推荐两种方式:
1. 本地构建时监控
在 project.config.json 里可以配置分包体积上限:
{
"setting": {
"preloadLimit": "2MB",
"subPackageSizeCheck": true
}
}
开启 subPackageSizeCheck 后,如果某个分包超过限制,构建时会直接报错。这能拦住大部分无意识的体积膨胀。
2. CI/CD 流水线监控
我在公司的CI流水线里加了一个脚本,每次构建后自动解析 subPackages 的体积,如果某个分包比上一次构建大了10%以上,就发告警通知。这样团队里每个人都能看到体积变化。
来看一个简单的体积监控脚本思路:
# 伪代码,实际用Node.js写
1. 构建完成后读取 dist 目录
2. 遍历每个分包文件夹,计算总大小
3. 与上一次构建的基线数据对比
4. 如果增长超过阈值,输出警告
总结一下
分包加载这件事,说白了就是把大包拆小,按需加载。主包放核心,分包放次要,独立分包放独立场景,预加载让用户感觉不到等待。最后用监控守住成果。
我个人觉得,分包策略做得好不好,直接决定了小程序启动速度和页面跳转体验。你想想看,用户打开小程序,1秒内看到首页,和3秒才看到首页,体验差距有多大?
下一节我会讲代码层面的极致优化,包括如何减少setTimeout、如何优化长列表渲染。咱们一步步来,把性能优化吃透。