微信小程序 setData 原理
渲染层和逻辑层
小程序的运行环境分成渲染层和逻辑层,其中 WXML 模板和 WXSS 样式工作在渲染层,JS 脚本工作在逻辑层。
小程序的渲染层和逻辑层分别由 2 个线程管理:渲染层的界面使用了 WebView 进行渲染;逻辑层采用 JsCore 线程运行 JS 脚本。一个小程序存在多个界面,所以渲染层存在多个 WebView 线程,这两个线程的通信会经由**微信客户端(Native)**做中转,逻辑层发送网络请求也经由 微信客户端 转发
通信机制
视图层和逻辑层的数据传输,实际上通过两边提供的 evaluateJavascript 所实现。即用户传输的数据,需要将其转换为字符串形式传递,同时把转换后的数据内容拼接成一份 JS 脚本,再通过执行 JS 脚本的形式传递到两边独立环境。
而 evaluateJavascript 的执行会受很多方面的影响,数据到达视图层并不是实时的。所以我们的 setData 函数将数据从逻辑层发送到视图层,是异步的。
小程序与普通网页开发的区别
网页开发渲染线程和脚本线程是互斥的,这也是为什么长时间的脚本运行可能会导致页面失去响应。
而在小程序中,二者是分开的,分别运行在不同的线程中。(渲染层和逻辑层)
网页开发者可以使用到各种浏览器暴露出来的 DOM API,进行 DOM 选中和操作。
小程序的逻辑层和渲染层是分开的,逻辑层运行在 JSCore 中,并没有一个完整浏览器对象,因而缺少相关的 DOM API 和 BOM API。
setData 的工作原理
1、调用 setData 方法;
2、逻辑层会执行一次 JSON.stringify 来去除掉 setData 数据中不可传输的部分,将待传输数据转换成字符串并拼接到特定的 JS 脚本, 并通过 evaluateJavascript 执行脚本将数据传输到渲染层。
3、渲染层接收到后, WebView JS 线程会对脚本进行编译,得到待更新数据后进入渲染队列等待 WebView 线程空闲时进行页面渲染。
4、WebView 线程开始执行渲染时,将 data 和 setData 数据套用在 WXML 片段上,得到一个新节点树。经过新虚拟节点树与当前节点树的 diff 对比,将差异部分更新到 UI 视图。最后,将 setData 数据合并到 data 中,并用新节点树替换旧节点树,用于下一次重渲染