微信小程序基础知识总结


1. 生命周期

小程序的生命周期

  • onLaunch:小程序初始化完成时触发,全局只触发一次。
  • onShow:小程序启动,或从后台进入前台显示时触发。
  • onHide:小程序从前台进入后台时触发。

页面的生命周期

  • onLoad:页面加载时触发。一个页面只会调用一次,可以在 onLoad 的参数中获取打开当前页面路径中的参数。
  • onShow:页面显示/切入前台时触发。
  • onReady:页面初次渲染完成时触发。一个页面只会调用一次,代表页面已经准备妥当,可以和视图层进行交互。
  • onHide:页面隐藏/切入后台时触发。
  • onUnload:页面卸载时触发。
  • onRouteDone:路由动画完成时触发。

2. 登录流程

  1. 调用wx.login()获取code传递给服务端;
  2. 服务端根据code换取unionIdopenid,同时生成登录凭证accessToken返回给小程序;
  3. 小程序将accessToken缓存到本地,后续请求都带上。
    微信登录流程

3. 支付流程

  1. 小程序调用服务端的下单接口;
  2. 服务端生成订单,并请求小程序支付统一下单接口,生成prepay_id等参数后返回给小程序;
  3. 小程序利用获取到的prepay_id等参数,调用wx.wx.requestPayment()拉起支付;
  4. 用户支付成功后,服务端可接收到微信的支付回调信息,进而修改订单的支付状态。
    小程序支付开发流程

4. 手机号授权流程

旧流程

  1. 调用wx.login()获取code,发送给后端,后端根据code得到session_key;
  2. button 组件 open-type 的值设置为 getPhoneNumber,当用户点击并同意之后,可以通过 bindgetphonenumber 事件回调获取到微信服务器返回的加密数据, 发送给后端;
  3. 后端结合 session_key 以及 app_id 进行解密获取手机号。

新流程

  1. button 组件 open-type 的值设置为 getPhoneNumber,当用户点击并同意之后,可以通过 bindgetphonenumber 事件回调获取到动态令牌code,然后把code传到后端;
  2. 后端调用微信后台提供的 phonenumber.getPhoneNumber 接口,消费code 来换取用户手机号。每个code有效期为5分钟,且只能消费一次。

5. 小程序的底层原理

小程序的运行环境分为两部分:逻辑层渲染层WXML 模板和 WXSS 样式工作在渲染层,JS 脚本工作在逻辑层。

通信模型

小程序的渲染层和逻辑层分别由2个线程管理:渲染层的界面使用了 WebView 进行渲染;逻辑层采用 JsCore 线程运行JS脚本。一个小程序存在多个界面,所以渲染层存在多个WebView 线程,这两个线程的通信会经由 Native(微信客户端)做中转,逻辑层发送网络请求也经由 Native 转发,
渲染层和逻辑层通信模型

小程序与客户端通信原理

  • 视图层组件
    内置组件中有部分组件是利用到客户端原生提供的能力。既然需要客户端原生提供的能力,那就会涉及到视图层与客户端的交互通信。这层通信机制在 iOS 和安卓系统的实现方式并不一样,iOS 是利用了 WKWebView 的提供 messageHandlers 特性,而在安卓则是往 WebViewwindow 对象注入一个原生方法,最终会封装成 WeiXinJSBridge 这样一个兼容层,主要提供了调用(invoke)和监听(on)这两种方法。
  • 逻辑层接口
    逻辑层与客户端原生通信机制与渲染层类似,不同在于,iOS平台可以往JavaScripCore框架注入一个全局的原生方法,而安卓方面则是跟渲染层一致的。

数据驱动原理

在渲染层,宿主环境会把WXML转化成对应的JS对象,在逻辑层发生数据变更的时候,需要通过宿主环境提供的setData方法把数据从逻辑层传递到渲染层,再经过对比前后差异,把差异应用在原来的Dom树上,渲染出正确的UI界面。
逻辑层传递数据到渲染层

事件触发原理

渲染层产生用户交互事件传递给逻辑层

6. 小程序性能优化

启动性能优化

  • 首次加载
    小程序启动时,微信会为小程序展示一个固定的启动界面,界面内包含小程序的图标、名称和加载提示图标。此时,微信会在背后完成几项工作:下载小程序代码包加载小程序代码包初始化小程序首页。下载到的小程序代码包不是小程序的源代码,而是编译、压缩、打包之后的代码包。
  • 加载顺序
    预加载(JS引擎/WebView初始化、公共库注入)—> 小程序启动(代码包下载、业务代码注入、渲染首屏)

由上可知,提升启动性能最直接的方法就是控制小程序包的大小。方法有:

  • 勾选开发者工具中上传代码时,自动压缩
  • 及时清理无用的代码和资源文件
  • 减少代码包内的资源,尽量使用CDN
  • 避免非必要的全局自定义组件和插件,因为这些内容会在小程序启动时随主包一起下载和注入 JS 代码,影响启动耗时
  • 采用分包加载,访问率高的页面放在主包,访问率低的页面放入子包
  • 采用分包预加载,提前下载在当前页可能用到的子包数据
  • 对于需要从子包启动的分包,采用独立分包

首屏渲染的优化方法:

  • 避免引用未使用的自定义组件
  • 异步请求放在onLoad,不要等onReady之后才请求数据
  • 精简首屏数据,优先展示页面的关键部分,对于非关键部分或者不可见的部分可以延迟更新
  • 利用storage API,对变动频率比较低的数据进行缓存,二次启动时可以使用缓存数据进行初始化渲染,然后网络请求后再进行数据更新
  • 尽量避免展示空白页面,而是先通过骨架屏展示页面的大致结构,请求数据返回后再进行页面更新。以提升用户的等待意愿

运行时性能优化

  • 合理使用 setData
    • data中 应只包括渲染相关的数据,渲染无关的数据,应挂在非 data 的字段下
    • setData只传发生变化的数据,并控制调用的频率
  • 避免不当的使用onPageScroll
    每一次事件监听都是一次视图到逻辑的通信过程,所以只在必要的时候监听pageSrcoll。同时避免在onPageScroll中执行复杂的逻辑及多次调用setData
  • 控制 WXML 节点数量和层级
    一个太大的 WXML 节点树会增加内存的使用,样式重排时间也会更长,影响体验。一个页面 WXML 节点数量应少于 1000 个,节点树深度少于 30 层,子节点数不大于 60 个。
  • 避免在 onHide/onUnload 执行耗时操作
    页面切换时,会先调用前一个页面的 onHide 或 onUnload 生命周期,然后再进行新页面的创建和渲染。如果 onHide 和 onUnload 执行过久,可能导致页面切换的延迟。若必须要进行部分复杂逻辑,可以考虑用 setTimeout 延迟进行。
  • 及时解绑事件监听及清理定时器
    事件监听结束后,应及时解绑监听器,比如摇一摇,定位等;开发「秒杀倒计时」等功能时,可能会使用 setInterval 设置定时器,页面或组件销毁前,需要调用 clearInterval 方法取消定时器。

参考文档

微信开放文档–性能与体验


文章作者: Snail-Lu
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Snail-Lu !
  目录