1

一、微信小程序宿主环境

微信小程序使用的技术栈是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框架。

clipboard.png

以上是官方提供的一张图。微信小程序的运行环境包含渲染层和逻辑层。渲染层负责页面的渲染工作,由wxml和wxss来负责呈现,逻辑层负责整个小程序js脚本运行。

渲染层和逻辑层是不同的线程在执行,渲染层 使用webView来渲染,逻辑层由jsCore线程来执行。微信小程序由多个页面组成,每一个页面都是一个webView线程。渲染层线程和逻辑层线程之间的通信需要借助于微信客户端Native来完成。同时逻辑层发送网络请求也需要我们的Native来提供支持。

看了官网提供的图,我们再来看另一个图。

clipboard.png

整个小程序只有一个App service。并且常驻内存。APP Service将数据绑定到我们的视图层,触发视图的更新,视图中通过事件监听来回调我们逻辑层的方法,在逻辑层去处理我们的逻辑,更新数据。视图层和逻辑层通过系统层Native中的JsBridge来实现通信。系统层提供了访问微信原生能力的能力,同时也为网络请求等提供服务。

App Service由两部分组成,一部分是Manager负责逻辑的执行,另一部分是API,对不同的平台微信为我们做了一层处理,使得我们可以通过同一个API接口来实现。

三、微信小程序的启动分类

clipboard.png

小程序启动会有两种情况,一种是「冷启动」,一种是「热启动」。

  • 热启动:假如用户已经打开过某小程序,然后在一定时间内再次打开该小程序,此时无需重新启动,只需将后台态的小程序切换到前台,这个过程就是热启动;
  • 冷启动:用户首次打开或小程序被微信主动销毁后再次打开的情况,此时小程序需要重新加载启动,即冷启动。

小程序没有重启的概念。

只有当小程序进入后台一定时间,或者系统资源占用过高,才会被真正的销毁。

四、微信小程序的启动机制

clipboard.png

1、首先从CDN加载我们的小程序包,然后加载运行,只有当页面放入WebView后才能显示出来。
2、下次我们运行的时候,(冷启动)会再次向CDN发送请求,去判断是否有更新信息,然后异步下载最新的代码包。
   我们下次启动的时候才能使用最新的代码。如果没有更新,则直接使用本地缓冲的代码包

五、微信小程序的生命周期

应用的生命周期

clipboard.png

当我们第一次启动小程序的时候,首先初始化小程序执行环境,然后会从本地缓冲或者是CDN下载代码包进行加载,当我们的小程序初始化完成之后,会触发APP实例的onLaunch方法,全局只调用一次。
当我们切换小程序到后台的时候调用onHide,当切回前台的时候调用的是onShow方法。当小程序发生脚本错误,或者 API 调用失败时,会触发 onError 并带上错误信息。

页面的生命周期

clipboard.png

  • 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

clipboard.png

上面是官网提供的一个图,我们可以分析一下~

1、小程序执行需要两个线程,一个是UI线程负责视图层,一个是AppService线程,负责逻辑处理。
2、AppService线程创建好之后会依次调用onLoad和onShow方法,我们可以在这里做一些数据请求操作
3、UI线程创建好之后会进行初始化工作,当初始化ok之后,会告诉AppService线程,此时AppService发送数据,提供给UI线程进行页面数据填充。然后页面进行初次渲染,渲染好之后告诉AppService线程,此时onReady回调开始触发。
4、期间AppService线程可以处理一些事件触发,从而更新data数据,重新触发视图的渲染。

针对路由变化,页面生命周期的调用

clipboard.png

总之页面出栈,会调用onUnload去销毁我们的页面,如果不出栈,调用onHide。

如何能好的掌握页面路由变化我们页面生命周期怎么变化,我们还需要知道路由变化的机制。

clipboard.png

  • tabbar页面的切换,我们可以参考官方文档。页面切换

注意

navigateTo, redirectTo 只能打开非 tabBar 页面。
switchTab 只能打开 tabBar 页面。
reLaunch 可以打开任意页面。
页面底部的 tabBar 由页面决定,即只要是定义为 tabBar 的页面,底部都有 tabBar。
调用页面路由带的参数可以在目标页面的onLoad中获取。

Meils
1.6k 声望157 粉丝

前端开发实践者