分包加载
1. 什么是分包加载
什么是分包加载 ❓
小程序的代码通常是由许多页面、组件以及资源等组成,随着小程序功能的增加,代码量也会逐渐增加,体积过大就会导致用户打开速度变慢,影响用户的使用体验。
分包加载是一种小程序优化技术。将小程序不同功能的代码,分别打包成不同的子包,在构建时打包成不同的分包,用户在使用时按需进行加载,在构建小程序分包项目时,构建会输出一个或多个分包。每个使用分包小程序必定含有一个主包。每个分包可以包含多个页面、组件、样式和逻辑等。当小程序需要使用某个分包时,才会加载该分包中的代码。
**主包:**包含默认启动页面 / TabBar 页面 以及 所有分包都需用到公共资源的包
**分包:**根据开发者的配置进行划分出来的子包
小程序分包后如何加载
在小程序启动时,默认会下载主包并启动主包内页面,在用户访问分包内某个页面时,微信客户端才会把对应分包下载下来,下载完成后再进行展示。
目前小程序分包大小有以下限制:**
- 整个小程序所有分包大小不超过 20MB
- 单个分包/主包大小不能超过 2MB
📌 注意事项:
整个小程序所有分包大小可能会随时调整,截止到目前整个小程序所有分包大小不超过 20M
###2. 分包的基本使用
知识点:
在进行分包加载之前,需要对小程序的业务逻辑进行分析,将代码划分成多个模块。每个模块应该有一个明确的功能,并与其他模块之间有明确的依赖关系
需要按照功能拆分分包,并且每个分包都需要与其他包有依赖关系(可以通过 a 分包跳转到 b 分包)
开发者在小程序的配置文件 app.json
中,通过 subPackages
或者 subpackages
字段声明项目分包结构。
每个分包需要指定 root
字段、name
字段和 pages
字段
root
字段指定了分包的根目录,该目录下的所有文件都会被打包成一个独立的包name
字段为分包的名称,用于在代码中引用该分包pages
字段指定了该分包中包含的页面,可以使用通配符*
匹配多个页面
、
落地代码:
{
"subPackages": [
{
"root": "modules/goodModule",
"name": "goodModule",
"pages": [
"pages/list/list",
"pages/detail/detail"
]
},
{
"root": "modules/marketModule",
"name": "marketModule",
"pages": [
"pages/market/market"
]
}
]
}
3. 打包和引用原则(注意事项)
打包原则:
-
tabBar 页面必须在主包内
-
最外层的 pages 字段,属于主包的包含的页面
-
按 subpackages 配置路径进行打包,配置路径外的目录将被打包到主包中
-
分包之间不能相互嵌套,subpackage 的根目录不能是另外一个 subpackage 内的子目录
引用原则:
-
主包不可以引用分包的资源,但分包可以使用主包的公共资源
-
分包与分包之间资源无法相互引用, 分包异步化时不受此条限制
4. 独立分包的配置
什么是独立分包:
独立分包:独立分包是小程序中一种特殊类型的分包,可以独立于主包和其他分包运行。
从独立分包中页面进入小程序时,不需要下载主包,但是当用户进入普通分包或主包内页面时,主包才会被下载 !
开发者可以将功能相对独立的页面配置到独立分包中,因为独立分包不依赖主包即可运行,可以很大程度上提升分包页面的启动速度
如果是独立分包,不需要下载主包,直接就能够访问,独立分包是自己独立运行的
而如果是其他分包,需要先下载主包,通过路径访问,才能加载对应路径的分包
📌 注意事项:
独立分包中不能依赖主包和其他分包中的资源
主包中的 app.wxss 对独立分包无效
App 只能在主包内定义,独立分包中不能定义 App,会造成无法预期的行为
如何配置独立分包:
开发者在app.json
中找到需要配置为独立分包的subpackages
字段
在该字段配置项中定义independent
字段声明对应分包为独立分包。
落地代码:
{
"subPackages": [
{
"root": "modules/goodModule",
"name": "goodModule",
"pages": [
"pages/list/list",
"pages/detail/detail"
]
},
{
"root": "modules/marketModule",
"name": "marketModule",
"pages": [
"pages/market/market"
],
+ "independent": true
}
]
}
5. 分包预下载
知识点:
分包预下载是指访问小程序某个页面时,预先下载分包中的代码和资源,以提高用户的使用体验。当用户需要访问分包中的页面时,已经预先下载的代码和资源可以直接使用,通过分包预下载加快了页面的加载速度和显示速度。
小程序的分包预下载需要在 app.json
中通过 preloadRule
字段设置预下载规则。preloadRule
是一个对象,对象的 key
表示访问哪个路径时进行预加载,value
是进入此页面的预下载配置,具有两个配置项:
字段 | 类型 | 必填 | 默认值 | 说明 |
---|---|---|---|---|
packages | StringArray | 是 | 无 | 预下载的分包名称,进入页面后预下载分包的 root 或 name __APP__ 表示主包。 |
network | String | 否 | wifi | 在指定网络下预下载, 可选值为: all : 不限网络 wifi : 仅wifi下预下载 |
{
"subPackages": [
{
"root": "modules/goodModule",
"name": "goodModule",
"pages": [
"pages/list/list",
"pages/detail/detail"
]
},
{
"root": "modules/marketModule",
"name": "marketModule",
"pages": [
"pages/market/market"
],
"independent": true
}
],
"preloadRule": {
"pages/index/index": {
"network": "all",
"packages": ["modules/goodModule"]
},
"modules/marketModule/pages/market/market": {
"network": "all",
"packages": ["__APP__"]
}
}
}
落地代码:
{
"pages": [
"pages/index/index",
"pages/user/user"
],
"subPackages": [
{
"root": "pages/music",
"name": "music",
"pages": [
"player/player",
"lyric/lyric"
]
},
{
"root": "pages/settings",
"name": "settings",
"pages": [
"theme/theme",
"language/language"
]
}
],
"preloadRule": {
"pages/music/player/player": {
"packages": ["settings"],
"network": "wifi"
}
}
}
## **框架接口-getApp**
`getApp()` 用于获取小程序全局唯一的 `App` 实例,通过小程序应用实例可实现数据或方法的共享
> 📌 **注意事项**:
>
> 1. 1.不要在 App() 方法中使用 getApp() ,使用 this 就可以拿到 app 实例
> 2. 通过 `getApp()` 获取实例之后,不要私自调用生命周期函数
**落地代码:**
`➡️ app.js`
```js
App({
// 全局共享的数据
globalData: {
token: ''
},
// 全局共享的方法
setToken (token) {
// 如果想获取 token,可以使用 this 的方式进行获取
this.globalData.token = token
// 在 App() 方法中如果想获取 App() 实例,可以通过 this 的方式进行获取
// 不能通过 getApp() 方法获取
}
})
➡️ pages/index/index.js
// getApp() 方法用来获取全局唯一的 App() 实例
const appInstance = getApp()
Page({
login () {
// 不要通过 app 实例调用钩子函数
console.log(appInstance)
appInstance.setToken('fghioiuytfghjkoiuytghjoiug')
}
})
6.小程序页面间通信
如果一个页面通过 wx.navigateTo
打开一个新页面,这两个页面间将建立一条数据通道
-
在
wx.navigateTo
的success
回调中通过EventChannel
对象发射事件 -
被打开的页面可以通过
this.getOpenerEventChannel()
方法获得一个EventChannel
对象,进行监听、发射事件 -
wx.navigateTo
方法中可以定义events
配置项接收被打开页面发射的事件
这两个 EventChannel
对象间可以使用 emit
和 on
方法相互发送、监听事件。
落地代码:
页面 .js 文件
Page({
// 点击按钮触发的事件处理函数
handler () {
wx.navigateTo({
url: '/pages/list/list',
events: {
// key:被打开页面通过 eventChannel 发射的事件
// value:回调函数
// 为事件添加一个监听器,获取到被打开页面传递给当前页面的数据
currentevent: (res) => {
console.log(res)
}
},
success (res) {
// console.log(res)
// 通过 success 回调函数的形参,可以获取 eventChannel 对象
// eventChannel 对象给提供了 emit 方法,可以发射事件,同时携带参数
res.eventChannel.emit('myevent', { name: 'tom' })
}
})
}
})
被页面 .js 文件
Page({
onLoad () {
// 通过 this.getOpenerEventChannel() 可以获取 EventChannel 对象
const EventChannel = this.getOpenerEventChannel()
// 通过 EventChannel 提供的 on 方法监听页面发射的自定义事件
EventChannel.on('myevent', (res) => {
console.log(res)
})
// 通过 EventChannel 提供的 emit 方法也可以向上一级页面传递数据
// 需要使用 emit 定义自定义事件,携带需要传递的数据
EventChannel.emit('currentevent', { age: 10 })
}
})
7.自定义导航栏
小程序默认的导航栏与 APP 一样都位于顶部固定位置。但是默认导航栏可能会影响小程序整体风格,且无法满足特定的设计需求,这时候,就需要进行自定义导航栏。
在 app.json 或者 page.json 中,配置 navigationStyle 属性为 custom,即可 自定义导航栏
在设置以后,就会移除默认的导航栏,只保留右上角胶囊按钮
落地代码:
{
"usingComponents": {},
"navigationStyle": "custom"
}
<!--pages/cate/cate.wxml-->
<!-- <text>pages/cate/cate.wxml</text> -->
<swiper class="custom-swiper" indicator-dots autoplay interval="2000">
<swiper-item>
<image src="../../assets/banner/banner-1.png" mode=""/>
</swiper-item>
<swiper-item>
<image src="../../assets/banner/banner-2.png" mode=""/>
</swiper-item>
<swiper-item>
<image src="../../assets/banner/banner-3.png" mode=""/>
</swiper-item>
</swiper>
/* pages/cate/cate.wxss */
.custom-swiper {
height: 440rpx;
}
.custom-swiper image {
height: 100%;
width: 100%;
}
以上资料均参考网络,希望对大家有所帮助!!!