双线程
| 小程序运行平台 | 逻辑层运行环境 | 视图层运行环境 |
|---|---|---|
| iOS | JavaScriptCore | 由 WKWebView 来渲染 |
| Android | V8 | 由自研 XWeb 引擎基于 Mobile Chrome 内核来渲染的 |
| 开发工具 | NW.js | Chromium Webview 来渲染 |
| PC | Chrome 内核 | Chrome 内核 |
| Mac | JavaScriptCore | 由 WKWebView 来渲染的 |
网页开发,渲染线程和脚本是互斥的,这也是为什么长时间的脚本运行可能会导致页面失去响应的原因,本质就是我们常说的 JS 是单线程的
而在小程序中,选择了 Hybrid 的渲染方式,将视图层和逻辑层是分开的,双线程同时运行,视图层的界面使用 WebView 进行渲染,逻辑层运行在 JSCore
- View 视图线程:主要提供各类组建、渲染界面
- App Service 逻辑线程:提供 API 处理业务逻辑
WeixinJSBridge
构建 Native 和非 Native 间消息通讯的通道,并且是 双向通讯的通道
可参考 js与webview通讯
作用
- 两个线程都是通过 WeixinJSBridge 与微信Native 底层进行通讯。
- 两个线程之间进行的事件与数据的交互,也是通过WeixinJSBridge来完成的。
- 所有的平台能力和硬件能力,也是通过 WeixinJSBridge 间接提供的。
视图更新
在视图层,wcc编译器会把wxml转化成对应的JS对象;
在逻辑层,wcsc编译器会把wxss转化成对应的JS对象;
- 在
逻辑层发生数据变更的时候,通过宿主环境提供的setData方法把数据从逻辑层传递到WeixinJSBridge; setData要求更新的数据首先会将这个数据转化成字符串,接着将这个字符串于代码拼接成JavaScript 脚本,最后,把拼接的内容传给视图webview去执行evaluateJavaScript()。- 再经过对比前后差异,把差异应用在原来的
Dom树上,渲染出正确的视图;
生命周期
onLoad,onShow,onReady,onHide,onUnload。
- 页面启动,首先触发的是onLoad和onShow生命周期函数
- 初始渲染:页面初始化装载完毕之后,Notify 通知逻辑线程,逻辑线程将初始化的Data数据发给视图线程,由视图线程渲染,完成首次渲染以后,视图线程通知逻辑线程渲染完成,派发onReady事件,监听到这个事件,代表着也没你可以进行交互了。
- 更新:此时,视图进入持续渲染状态,在运行状态下,用户触发了更新事件,如输入等操作,会触发逻辑线程的事件函数,可能触发了setData(),又向视图线程发送更新数据,视图线程再次执行更新
- 当用户跳转到其他小程序或者离开微信时,小程序进入后台状态,此时逻辑线程派发onHide事件。
- 而当后台切入前台时,又会从onShow事件开始走
- 如果页面页面被销毁,则会派回onUnload事件
事件
当视图存在交互的时候,例如用户点击你界面上某个按钮,这类反馈由视图层通知给开发者逻辑层;
对于事件的分发处理,微信进行了特殊的处理,将所有的事件拦截后,丢到逻辑层进行处理,最后通过setData去更新视图层
WXS
- WXS 是 weinxinScript 的缩写,WXS 是逻辑代码,它是运行在视图线程里的,通过直接操作视图数据,避免了跨线程的通讯开销。
- WXS 运行环境和其他JS代码是隔离的,因此,WXS是不可以调用JavaScript 代码里定义的函数的,也是不可以调用小程序提供的wx 开头的 API接口