小程序分包加载
小程序分包加载的出现是为了按需加载,优化小程序的启动时间。
开发者可以可以将小程序分成一个主包和多个子包,这样构建时可以打多个包,当用户进入那个页面时加载那个包的内容。
其中每个小程序必须要有一个主包,主包放着项目启动页面和tabBar页面,还有一个公共资源,当项目启动时只会下载主包里的内容,不会下载子包中的东西。
小程序大小:整个小程序大小不能超过20兆,主包或每个子包不能超过2兆。
具体使用方法:
- 分包
- 独立分包
- 分包预下载
- 分包异步化
分包
在app.json
设置subpackages
属性
例如:
{
"subpackages": [
{
"root": "pages/face",
"name": "face",
"pages": [
"face/index",
"a/index"
]
},
{
"root": "pages/wx",
"name": "fa",
"pages": [
"a/index",
"b/index"
]
}
],
"pages": [
"pages/pagehome/index",
"pages/login/index"
]
}
subpackages
每个分包都有几个属性
root
: String 分包的根目录
name
:String 分包的别名
pages
:Array 分包的页面路径
independent
:Boolean 是否是独立包
打包原则
pages
内的内容会被打包到主包内,subpackages
中的内容会打成多个包。- tabBar页会被打包到主包内。
- 一个子包不能内嵌另一个子包即
subpackages
中再声明一个subpackages
。
引用原则
- 各个子包之间的资源不能引用
- 子包可以引用主包内容
独立分包
独立分包是分包的一种,在subpackages
中新增independent
属性即可实现该分包变成独立分包。
独立分包可以在主包和其他子包之外运行,意思说不用下载主包也能运行独立包。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GggC6EWd-1662797711182)(D:\Download\softwareDownload\微信公众号\微信截图_20220909104528.png)]
引用原则
- 独立包的资源是私有的不能引入主包里的公共资源
- 独立包与独立包直接的资源不能使用
- 独立包不能引入分包内容
独立包与分包区别
- 独立包不能引入主包内容,分包可以引入主包内容
- 分包必须依赖主包运行
例如:
{
"subpackages": [
{
"root": "pages/face",
"name": "face",
"pages": [
"face/index",
"a/index"
]
},
{
"root": "pages/wx",
"name": "fa",
"independent": true,
"pages": [
"a/index",
"b/index"
]
}
],
"pages": [
"pages/pagehome/index",
"pages/login/index"
]
}
分包预下载
可以当用户进入某个页面时,可以提前加载某些分包,可以加快后续页面的加载速度。
配置方法
在app.json
中加入preloadRule
属性
{
"pages": ["pages/index"],
"subpackages": [
{
"root": "a",
"pages": ["index"],
},
{
"name": "hello",
"root": "path/to",
"pages": ["index"]
},
{
"root": "c",
"pages": ["index"]
}
],
"preloadRule": {
"a/index": {
"network": "all",
"packages": ["hello", "c"]
}
}
}
在preloadRule
属性中其中key
代表用户进入某个页面的路径,value
则是配置要预加载的包。
value
的配置项:
packages
:StringArray 必填 进入页面后预下载分包的 root
或 name
。__APP__
表示主包
network
:String 选填 在指定网络下预下载,可选值为: all
: 不限网络 wifi
: 仅 wifi 下预下载
注意点:
预下载的包总大小不能超过2兆,比如预加载多个,则多个包总共大小不能超过2兆。
分包异步化
是为了解决包与包之间不能引用各自的资源内容,但可以通过异步化可以实现,包与包之间跨组件,跨方法。通过componentPlaceholder
配置
跨组件
就是一个包使用其他包中的自定义组件时,因为其他包还未下载下来,可以为这个自定义组件用其他组件替代,等到下载完成再替换回来。
方法:
- 当使用一个跨组件时,提前替换相应的标签或组件,比如使用标签
view
代替button
,实现提前占位。 - 进行下载包并且注入包
- 将占位组件换成真正的组件
// subPackageA/pages/index.json
{
"usingComponents": {
"button": "../../commonPackage/components/button",
"list": "../../subPackageB/components/full-list",
"simple-list": "../components/simple-list"
},
"componentPlaceholder": {
"button": "view",
"list": "simple-list"
}
}
在包``subPackageA引入了包
commonPackage中的自定义组件
button,在渲染时,会将
button渲染成
view标签,等包下载完成后再渲染成
button`
引入了包subPackageB
中的list
组件,在渲染时,会将list
组件渲染成simple-list
组件,等包下载完成后再渲染成list
跨分包JS代码引用
意思是说包A能调用包B的代码或插件,但是为了不阻碍代码下载,需要异步获取内容。
格式:
// subPackageA/index.js
// 使用回调函数风格的调用
require(param, res => {
console.log(res.a) // Wechat MiniProgram
}, ({mod, errMsg}) => {
console.error(`path: ${mod}, ${errMsg}`)
})
// 或者使用 Promise 风格的调用
require.async(param).then(res => {
res.getPackageName()
}).catch(({mod, errMsg}) => {
console.error(`path: ${mod}, ${errMsg}`)
})
param
类型String,在调用代码时意思是包B的路径,如果是调用的插件则是插件的名称
res
指调用返回的结果集