小程序的分包、独立分包和分包预下载分别解决什么问题?
说明 subPackages 的配置与引用规则、独立分包的启动特性与限制、preloadRule 预下载配置,以及分包异步化的作用。
参考答案
简答
- 分包把页面按功能拆成主包和多个分包,启动时只下载主包,进入分包页面时再下载对应分包,官方称之为优化启动耗时效果最明显的手段。
- 分包之间不能互相引用 JS、template 和资源,只能引用主包和自身的内容;tabBar 页面必须放在主包。
- 独立分包不依赖主包即可运行,从独立分包页面启动时不下载主包,适合活动页、广告页等独立场景,代价是不能使用主包内容,
getApp()可能拿不到 App。 - 分包预下载通过
app.json的preloadRule配置,在进入某个页面时提前下载后续可能用到的分包,减少首次进入分包页面的等待。 - 分包异步化把粒度细化到组件和文件,让主包里的部分组件和逻辑也能拆到分包中异步加载。
普通分包
json
{
"pages": ["pages/index", "pages/logs"],
"subPackages": [
{ "root": "packageA", "pages": ["pages/cat", "pages/dog"] },
{ "root": "packageB", "name": "pack2", "pages": ["pages/apple"] }
]
}
规则:
subPackages配置路径以外的目录都会打进主包,分包根目录不能嵌套在另一个分包里。- packageA 不能
requirepackageB 的 JS,不能引用 packageB 的 template 和资源,但可以使用主包和自己的内容(使用分包异步化时 JS 不受此限制)。 - 多个分包都会用到的工具代码应放在主包;只在某个分包用到的组件和插件应在分包内引用,而不是写在
app.json的全局usingComponents里,否则会随主包一起下载和注入。
独立分包
在分包配置中加 "independent": true 即可声明独立分包,一个小程序可以有多个。
限制和注意事项:
- 不能依赖主包和其他分包的 JS、template、wxss、自定义组件、插件(分包异步化场景下 JS、自定义组件、插件除外)。
- 主包的
app.wxss对独立分包无效;独立分包里不能定义App。 - 从独立分包启动时
App还没注册,getApp()返回undefined。可以用getApp({ allowDefault: true })拿到默认实现,主包加载后其中的属性会合并到真正的 App 上。 - App 的
onLaunch和首次onShow会推迟到首次进入主包或普通分包页面时才调用,独立分包内要监听应用生命周期可以使用wx.onAppShow、wx.onAppHide。 - 在不支持独立分包的旧版微信上,独立分包按普通分包处理,主包的
app.wxss可能影响它的样式,所以不要依赖app.wxss。
分包预下载
json
{
"preloadRule": {
"pages/index": { "network": "all", "packages": ["important"] },
"indep/index": { "packages": ["__APP__"] }
}
}
- key 是触发预下载的页面路径,
packages填分包的root或name,__APP__表示主包,可以让独立分包页面提前下载主包。 network默认是wifi,设为all表示任何网络都预下载。- 目前只能通过配置使用,不能用 API 触发。
- 同一个分包内的页面共享预下载大小限额,官方文档写明为 2M,打包时由工具校验。
常见追问
- 分包能放多少代码?官方文档写明单个代码包上限为 2M,整个小程序所有分包不超过 30M(服务商代开发的小程序不超过 20M),单个分包或主包不能超过 2M(见微信开放文档《分包加载》)。
- 图片要放进分包吗?代码包中的图片、字体等资源很难再压缩,对下载耗时影响比代码大,官方建议放到 CDN 用 URL 引用,包内只保留小图标。