小程序底层原理
参考:https://www.bilibili.com/video/BV1Mh411h7JQ
双线程设计
小程序有渲染层(webview线程管理)和逻辑层(客户端js解释引擎线程)组成。
- 提升安全性
- 逻辑层无法直接获取到渲染层的元素dom;
- 对js语法限制(不能new对象,page外面执行脚本等),防止xss攻击;
- 防止开发者获取用户敏感数据;
- 提升页面加载性能
- 逻辑代码执行不影响页面的渲染,区别于h5的单线程
渲染层和逻辑层都基于客户端Native作为桥接进行间接通信:
- 在渲染层中,将axml的模板语法转化成对应的vdom对象
- 在逻辑层发送数据变更的时候,通过宿主环境提供的setData方法把变更从逻辑层传到客户端Native,再转发到渲染层
- 渲染层中进行vdom前后差异对比,把差异应用在原来的vdom上面,实现页面更新。
渲染层渲染页面过程
页面渲染在渲染层维护vdom并进行diff。
初始渲染
渲染层在接收到初始数据data时,需要进行渲染层渲染:
- 初始渲染时,将初始数据data用于axml模板直接生成vdom
- 初始渲染生成的vdom和初始的data都会保留下来,用于重渲染
重渲染
渲染层在接收到**更新数据(setData)**时,需要进行渲染层渲染:
- 逻辑层异步setData通知渲染层,在每次重新渲染时,都会用最新的data结合axml模板生成vdom
- 渲染层将数据更新前后的vdom进行差异对比,通过在真实dom上打补丁,实现页面重渲染
自定义组件的渲染
组件渲染时逻辑层和渲染层都维护vdom。(因为组件的声明周期较多,组件可以作成是页面的超集)
小程序自定义组件用到了web components的技术。
- Custom elements(自定义元素)
- Shadow DOM(将多个dom组成的组件在模板中以一个元素的形式在dom上呈现)
- HTML templates(template和slot)
渲染过程
- 逻辑层新建组件,并通知渲染层
- 逻辑层生成vdom,通过客户端native通知并传递vdom到渲染层
- 渲染层拿到vdom,创建shadow dom,并拼接shadow tree,注入初始数据进行初次渲染
- 逻辑层调用setData,更新数据到渲染层
- 逻辑层执行逻辑,调用setData之后,会在逻辑层进行dom diff,然后将diff结果传递到渲染层(跟页面渲染流程不一致)
- 渲染层应用更新
- 渲染层拿到diff后的vdom,并更新页面
原生组件的同层渲染
由于原生组件脱离了WebView渲染流程,导致原生组件的层级最高。
同层渲染:小程序通过某种hack的方式将原生组件插入可控层级的方式,使得原生组件的层级和非原生组件一样可控,从而解决遮挡问题。