简述微信小程序原理?
- 小程序本质就是一个单页面应用,所有的页面渲染和事件处理,都在一个页面内进行,但又可以通过微信客户端调用原生的各种接口;
- 它的架构,是数据驱动的架构模式,它的UI和数据是分离的,所有的页面更新,都需要通过对数据的更改来实现;
- 它从技术讲和现有的前端开发差不多,采用JavaScript、WXML、WXSS三种技术进行开发;
- 功能可分为webview和appService两个部分;
- webview用来展现UI,appService有来处理业务逻辑、数据及接口调用;
- 两个部分在两个进程中运行,通过系统层JSBridge实现通信,实现UI的渲染、事件的处理等。
小程序与普通网页开发的区别
-
网页开发渲染线程和脚本线程是一个进程。小程序二者是分开的,分别运行在不 同的线程。
-
网页开发者可以操作DOM和BOM。小程序缺少操作DOM和BOM的方法。导致了例如jq、zepto等在小程序中无法运行。
-
小程序的运行环境与nodejs环境也不相同,所以一些npm的包在小程序中也是无法运行的。(从小程序基础版本2.2.1开始支持使用npm安装第三方宝)
微信小程序: wx:key详解
列表数据发生改变重新出发页面渲染的时候,列表中的项目可以保持自身状态
在不使用 wx:key的情况下, 如果 数据发生改变,则会重新创建每个Item对象然后渲染列表(费时费力)
在使用 wx:key的情况下,如果的数据发生改变,只是将对应的对象重新排序。未发生变化的对象,不会重新渲染(Very good),从而提高页面渲染性能的效率
另外:如不提供 wx:key,会报一个 warning, 如果明确知道该列表是静态,或者不必关注其顺序,可以选择忽略
wx:if 和hidden 区别
wx:if在切换时有局部渲染的过程,从而保证条件块渲染时,可以销毁并重新渲染,有更高的切换消耗 hidden始终渲染。可以控制视图上的显示和隐藏,有更高的初始化渲染消耗, 所以元素频繁切换的话,使用hidden
小程序运行机制
小程序两种启动方式:冷启动,热启动
- 热启动:假如用户已经打开了某个小程序,在一定时间内再次打开小程序的话,这个时候我们就不再需要重新启动了,这需要把我们的后台打开的小程序切换到前台来使用。
- 冷启动:用户首次打开小程序或被微信主动销毁再次打开的情况,此时小程序需要重新加载启动。
小程序什么时候会主动销毁?
- 小程序在进入后台之后,客户端会帮我们在一定时间内维持我们的一个状态,超过五分钟后,会被微信主动销毁
- 当我们在短时间内连续两次收到系统告警的时候,微信就会主动销毁,短时间间隔是5s
小程序更新机制:
小程序在冷启动的时候遇到版本更新,小程序会异步加载,帮我们下载最新版本的代码包,并同时使用微信本地版本的代码包启动,也就是说最新的代码包,将在小程序下次启动才去加载。如果偏要使用最新版本的代码包,我们可以使用api来处理
wx.getUpdateManager
const updateManager = wx.getUpdateManager()
updateManager.onCheckForUpdate(function (res) {
// 请求完新版本信息的回调
console.log(res.hasUpdate)
})
updateManager.onUpdateReady(function () {
wx.showModal({
title: '更新提示',
content: '新版本已经准备好,是否重启应用?',
success(res) {
if (res.confirm) {
// 新的版本已经下载好,调用 applyUpdate 应用新版本并重启
updateManager.applyUpdate()
}
}
})
})
updateManager.onUpdateFailed(function () {
// 新版本下载失败
})
小程序加载机制:
小程序的启动流程图里面:
左侧的部分是在启动的时候,微信客户端里面的视图层和逻辑层一些交互逻辑以及数据缓存的存取操作,在小程序启动的时候,会向cdn请求最新代码包,第一次启动必须等到代码包下载完毕,注入到webView容器内执行之后,才能看到小程序页面,所以在网络不好的情况下,我们会感觉到页面打开比较慢,客户端会帮我们把代码包缓存到本地,当我们下一次启动的时候,我们会从 cdn 请求是否有最新版本的代码包。
小程序事件模型
- 事件捕获阶段
绑定的事件从最外层节点向下传递到目标节点元素,依次检查,所经过的节点是否绑定了同一事件类型的监听回调函数,如果有则执行对应的事件回调函数 - 事件处理阶段
事件在到达目标节点之后,会触发目标节点所绑定的监听回调函数 - 事件冒泡阶段
事件从目标节点,向上冒泡到最外层节点,依次检查经过的节点是否绑定了,同样事件类型的监听回调函数,如果有,会执行这个回调函数
target属性: 触发事件的当前组件
currentTarget属性: 触发事件的根源组件
eg: 如果有外层view还有个里层view嵌套,都通过bind绑定了点击事件,target为外层view组件的事件对象,currentTarget为底层view组件的事件对象
- type 触发事件的触发类型
- timestamp 触发事件的时间戳
- target 触发事件的根源组件,包括触发事件根源组件的id自定义属性的集合
- currenTarget 事件绑定额当前组件 ,包括当前组件的id,类型,data自定义属性的集合
- touches 是一个数组,每一个元素都是一个touch对象 ,标识当前停留在屏幕上的触摸点和信息
- changedTouches 是一个数据,标识有变化的 触摸点,即当前触摸点从有到无或从无到有的变化
- detail 标识各个事件带有的数据,点击事件: ‘触摸点距离文档左上角的距离’
- 媒体事件,触发事件的时候播放状态,以及时间戳
如何分包加载?分包加载的优势在哪?
分包加载的介绍
大部分小程序都会由某几个功能组成,通常这几个功能之间是独立的,但会依赖一些公共的逻辑,并且这些功能通常会对应某几个独立的页面。那么小程序代码的打包,大可不必一定要打成一个,可以按照功能的划分,拆分成几个分包,当需要用到某个功能时,才加载这个功能对应的分包。
对于用户来说,小程序加载流程变成了:
1.首次启动时,先下载小程序主包,显示主包内的页面;
2.如果用户进入了某个分包的页面,再下载这个对应分包,下载完毕后,显示分包的页面。
采用分包加载,对开发者而言,能使小程序有更大的代码体积,承载更多的功能与服务;而对用户而言,可以更快地打开小程序,同时在不影响启动速度前提下使用更多功能。
分包的大小
- 小程序要求压缩包体积不能大于2M,否则无法发布
- 实际开发中小程序体积如果大于2M就需要使用分包机制进行发布上传
- 分包后可解决2M限制,并且能分包加载内容,提高性能
- 分包后单个包的体积不能大于2M
- 分包后所有包的体积不能大于12M
分包形式
- 常规分包
- 独立分包
- 分包预下载
常规分包 - 开发者通过在 app.json subpackages 字段声明项目分包结构
- 特点:
a) 加载小程序的时候先加载主包,当需要访问分包的页面时候才加载分包内容
b) 分包的页面可以访问主包的文件,数据,图片等资源
c) 主包:
i. 主包来源: 除了分包以外的内容都会被打包到主包中
ii. 通常放置启动页/tabBar页面
8.8.4 独立分包
- 设置independent为true
- 特点:
a) 独立分包可单独访问分包的内容,不需要下载主包
b) 独立分包不能依赖主包或者其他包的内容 - 使用场景
a) 通常某些页面和当前小程序的其他页面关联不大的时候可进行独立分包
b) 如:临时加的广告页 || 活动页
8.8.5 分包预下载
-
配置
a) app.json中设置preloadRule选项
b) key(页面路径): {packages: [预下载的包名 || 预下载的包的根路径])}
-
特点:
a) 在加载当前包的时候可以设置预下载其他的包
b) 缩短用户等待时间,提高用户体验
8.8.6 分包效果演示
8.8.7 官网对应地址
https://developers.weixin.qq.com/miniprogram/dev/framework/subpackages.html