微信小程序

小程序的原理?小程序如何与微信客户端(Native)进行交互的?

双线程选型

小程序的渲染层和逻辑层分别由2个线程管理:渲染层的界面使用了 WebView 进行渲染;逻辑层采用 JsCore 线程运行JS脚本。 Native 代指微信客户端

数据驱动

WXML结构实际上等价于一棵Dom树,通过一个JS对象也可以来表达Dom树的结构

小程序渲染页面

把WXML和对应的data数据 => JS对象 => DOM树(渲染展示出来)

双线程下的界面渲染

小程序的数据更新

小程序的逻辑层和渲染层是分开的两个线程。在渲染层,宿主环境会把 WXML 转化成相应的 JS 对象,在逻辑层发生数据变更的时候,通过宿主环境提供的 setData 方法将数据从逻辑层传递到渲染层,再经过对比前后差异,把差异应用在原来的 DOM 树上,进而渲染出正确的 UI 界面,如下图所示。其实就是采用了虚拟 DOM 的思想。

具体详细步骤(官网的例子很好,一定要看!):教程 | 《小程序开发指南》open in new window

小程序与客户端通信原理

视图层组件

内置组件中有部分组件是利用到客户端原生提供的能力,这类组件基本都是前一个章节描述的原生组件。既然需要客户端原生提供的能力,那就会涉及到视图层与客户端的交互通信。这层通信机制在 iOS 和安卓系统的实现方式并不一样,iOS 是利用了WKWebView 的提供 messageHandlers 特性,而在安卓则是往 WebView 的 window 对象注入一个原生方法,最终会封装成 WeiXinJSBridge 这样一个兼容层,主要提供了调用(invoke)和监听(on)这两种方法。

实际上,在视图层与客户端的交互通信中,开发者只是间接调用的,真正调用是在组件的内部实现中。开发者插入一个原生组件,一般而言,组件运行的时候被插入到 DOM 树中,会调用客户端接口,通知客户端在哪个位置渲染一块原生界面。在后续开发者更新组件属性时,同样地,也会调用客户端提供的更新接口来更新原生界面的某些部分。

逻辑层接口

逻辑层与客户端原生通信机制与渲染层类似,不同在于,iOS平台可以往JavaScripCore框架注入一个全局的原生方法,而安卓方面则是跟渲染层一致的。

同样地,开发者也是间接地调用到与客户端原生通信的底层接口。一般我们会对逻辑层接口做层封装后才暴露给开发者,封装的细节可能是统一入参、做些参数校验、兼容各平台或版本问题等等。

小程序和Web的区别

  1. 安全可控,沙箱隔离,限制 DOM 和 BOM 能力

    • 不允许跳转至其他网页;

    • 不允许直接操作 DOM;

    • 不允许随意使用 window 上的某些未知的可能有危险的 API;

  2. 性能

    • 在浏览器网页中,虽然 JS 执行和 UI 渲染也是处于两个线程,但是 JS 线程和 UI 线程是互斥的(之所以设计为互斥的主要是 JS 可以操作 DOM,所以必须设计为互斥的才能避免二者的不同步问题);

    • 在小程序中,逻辑层和渲染层是独立的,二者不会互相阻塞,因此性能更优(小程序限制了 JS 操作 DOM 的能力,因此不用担心二者的不同步问题);

Last Updated:
Contributors: mrkleo