共计 2872 个字符,预计需要花费 8 分钟才能阅读完成。
一、微信小程序宿主环境
微信小程序使用的技术栈是 js/wxml/wxss。跟我们 web 开发使用的技术栈存在一些不同。
- js:微信小程序的 js 运行是基于微信客户端,或者只微信 APP 上下文来运行的,并不是在浏览器中运行,因此它不能访问浏览器环境下的 DOM 对象,也不能访问 node.js 下的操作系统 API 等。
- wxml:是微信提供的一种新的基于 XML 的语法格式,作为微信小程序的展示层,提供整个页面的结构。
- wxss:是一套用于修饰微信组件的样式语言。wxss 具有大部分的 css 特性,但是仍存在一些其他的不足。
微信小程序运行在三端:iOS、Android 和 用于调试的开发者工具
在 iOS 上,小程序逻辑层的 javascript 代码运行在 JavaScriptCore 中,视图层是由 WKWebView 来渲染的,环境有 iOS8、iOS9、iOS10;在 Android 上,旧版本,小程序逻辑层的 javascript 代码运行中 X5 JSCore 中,视图层是由 X5 基于 Mobile Chrome 57 内核来渲染的;新版本,小程序逻辑层的 javascript 代码运行在 V8 中,视图层是由自研 XWeb 引擎基于 Mobile Chrome 67 内核来渲染的;在 开发工具上,小程序的 javascript 代码是运行在 nwjs(chrome 内核)中,mwjs 是合并 browser 和 node 的运行时,使用前端技术来开发跨平台的应用,微信小程序开发工具就是使用其开发的。
注意:三端环境各不相同,虽然提供了类似的实现,但是还是存在一些不同,JavaScript 语法和 API 支持不一致,我们可以通过开启 ES6 自动转换来规避一些问题。
具体的 js 支持情况,我们可以参考官方文档。
JavaScript 支持情况
二、MINA 框架解析
微信小程序的底层框架我们又称为是 MINA 框架。
以上是官方提供的一张图。微信小程序的运行环境包含渲染层和逻辑层。渲染层负责页面的渲染工作,由 wxml 和 wxss 来负责呈现,逻辑层负责整个小程序 js 脚本运行。
渲染层和逻辑层是不同的线程在执行,渲染层 使用 webView 来渲染,逻辑层由 jsCore 线程来执行。微信小程序由多个页面组成,每一个页面都是一个 webView 线程。渲染层线程和逻辑层线程之间的通信需要借助于微信客户端 Native 来完成。同时逻辑层发送网络请求也需要我们的 Native 来提供支持。
看了官网提供的图,我们再来看另一个图。
整个小程序只有一个 App service。并且常驻内存。APP Service 将数据绑定到我们的视图层,触发视图的更新,视图中通过事件监听来回调我们逻辑层的方法,在逻辑层去处理我们的逻辑,更新数据。视图层和逻辑层通过系统层 Native 中的 JsBridge 来实现通信。系统层提供了访问微信原生能力的能力,同时也为网络请求等提供服务。
App Service 由两部分组成,一部分是 Manager 负责逻辑的执行,另一部分是 API,对不同的平台微信为我们做了一层处理,使得我们可以通过同一个 API 接口来实现。
三、微信小程序的启动分类
小程序启动会有两种情况,一种是「冷启动」,一种是「热启动」。
- 热启动:假如用户已经打开过某小程序,然后在一定时间内再次打开该小程序,此时无需重新启动,只需将后台态的小程序切换到前台,这个过程就是热启动;
- 冷启动:用户首次打开或小程序被微信主动销毁后再次打开的情况,此时小程序需要重新加载启动,即冷启动。
小程序没有重启的概念。
只有当小程序进入后台一定时间,或者系统资源占用过高,才会被真正的销毁。
四、微信小程序的启动机制
1、首先从 CDN 加载我们的小程序包,然后加载运行,只有当页面放入 WebView 后才能显示出来。2、下次我们运行的时候,(冷启动)会再次向 CDN 发送请求,去判断是否有更新信息,然后异步下载最新的代码包。我们下次启动的时候才能使用最新的代码。如果没有更新,则直接使用本地缓冲的代码包
五、微信小程序的生命周期
应用的生命周期
当我们第一次启动小程序的时候,首先初始化小程序执行环境,然后会从本地缓冲或者是 CDN 下载代码包进行加载,当我们的小程序初始化完成之后,会触发 APP 实例的 onLaunch 方法,全局只调用一次。
当我们切换小程序到后台的时候调用 onHide,当切回前台的时候调用的是 onShow 方法。当小程序发生脚本错误,或者 API 调用失败时,会触发 onError 并带上错误信息。
页面的生命周期
- onLoad 页面第一次加载的时候调用,只调用一次,此时我们可以拿到一些页面的打开参数。
- onShow 页面显示或者从后台切回前台的时候调用的,该方法可能会调用多次,比如我们页面的跳转和返回,都会调用 onShow。
- onHide 页面隐藏或者切到后台会调用,也是会调用多次。
- onReady 页面渲染完成之后调用,一个页面只调用一次。
- onUnload 页面销毁的时候调用,比如我们点击返回键,那么当前页面会销毁执行 onUnload。
我们结合页面跳转来分析一下页面生命周期的调用顺序~
假如我们有 index 和 logs 页面。index 为首页,index 有一按钮可以跳转到 logs
1、第一次进入,先调用 app 实例的 onLaunch 和 onShow。2、调用 index 页面的 onLoad、onShow、onReady
3、点击按钮:调用 index 的 onHide,然后调用 logs 的 onLoad、onShow、onReady
4、点击左上角的返回,先调用 logs 的 onUnload, 然后调用 index 的 onShow
5、点击按钮:调用 index 的 onHide,然后调用 logs 的 onLoad、onShow、onReady
上面是官网提供的一个图,我们可以分析一下~
1、小程序执行需要两个线程,一个是 UI 线程负责视图层,一个是 AppService 线程,负责逻辑处理。
2、AppService 线程创建好之后会依次调用 onLoad 和 onShow 方法,我们可以在这里做一些数据请求操作
3、UI 线程创建好之后会进行初始化工作,当初始化 ok 之后,会告诉 AppService 线程,此时 AppService 发送数据,提供给 UI 线程进行页面数据填充。然后页面进行初次渲染,渲染好之后告诉 AppService 线程,此时 onReady 回调开始触发。
4、期间 AppService 线程可以处理一些事件触发,从而更新 data 数据,重新触发视图的渲染。
针对路由变化,页面生命周期的调用
总之页面出栈,会调用 onUnload 去销毁我们的页面,如果不出栈,调用 onHide。
如何能好的掌握页面路由变化我们页面生命周期怎么变化,我们还需要知道路由变化的机制。
- tabbar 页面的切换,我们可以参考官方文档。页面切换
注意
navigateTo, redirectTo 只能打开非 tabBar 页面。switchTab 只能打开 tabBar 页面。reLaunch 可以打开任意页面。页面底部的 tabBar 由页面决定,即只要是定义为 tabBar 的页面,底部都有 tabBar。调用页面路由带的参数可以在目标页面的 onLoad 中获取。