前端的框架太多让人眼花缭乱,很多相似的地方,优秀的地方大家都会借鉴,同时又会有各自的一些特点。小程序也好,其他框架也好,理解他们的设计缘由、实现原理,还是能学到很多很多东西的。
上一节《小程序的诞生》中,我们也提到了小程序的双线程设计。
目前来说,页面渲染的方式主要有三种:
前面也说过,小程序最终的呈现形式,是 WebView + 原生组件,Hybrid 方式。我们结合之前对小程序的期望来看:
由于小程序的宿主是微信,如果用纯客户端原生技术来编写小程序 ,那小程序代码需要与微信代码一起编包,跟随微信发版本,这种方式跟开发节奏必然都是不对的。
所以方向应该是需要像 Web 技术那样,有一份随时可更新的资源包放在云端,通过下载到本地,动态执行后即可渲染出界面。
如果用纯 Web 技术来渲染小程序,在一些有复杂交互的页面上可能会面临一些性能问题。
这是因为在 Web 技术中,UI渲染跟 JavaScript 的脚本执行都在一个单线程中执行,这就容易导致一些逻辑任务抢占UI渲染的资源。
总地看来,小程序选择了 Hybrid 的渲染方式,可以用一种近似 Web 的方式来开发,并且还可以实现在线更新代码。同时,引入原生组件有以下好处:
现在,我们还剩下一个很重要的问题:管控性和安全性。于是,双线程的设计被提出来了。
也不知道是哪位大佬,能想出双线程这样的模型,反正我是佩服得666的。
双线程是什么?我们先来看个官方的图:
小程序的渲染层和逻辑层分别由 2 个线程管理:渲染层的界面使用了 WebView 进行渲染,逻辑层采用 JsCore 线程运行 JS 脚本。
为什么要这么设计呢?前面提到的管控和安全,为了解决这些问题,我们需要阻止开发者使用一些浏览器提供的,诸如跳转页面、操作 DOM、动态执行脚本的开放性接口。
我们可以使用客户端系统的 JavaScript 引擎,iOS下的 JavaScriptCore 框架,安卓下腾讯 x5 内核提供的 JsCore 环境。通过提供一个沙箱环境来运行开发者的 JavaScript 代码来解决。这个沙箱环境只提供纯 JavaScript 的解释执行环境,没有任何浏览器相关接口。
这就是小程序双线程模型的由来:
把开发者的 JS 逻辑代码放到单独的线程去运行,但在 Webview 线程里,开发者就没法直接操作 DOM。那要怎么去实现动态更改界面呢?
前面我们知道,逻辑层和渲染层的通信会由 Native (微信客户端)做中转,逻辑层发送网络请求也经由 Native 转发。这是不是意味着,我们可以把 DOM 的更新通过简单的数据通信来实现呢?
Virtual DOM 相信大家都已有了解,大概是这么个过程:用JS对象模拟DOM树 -> 比较两棵虚拟DOM树的差异 -> 把差异应用到真正的DOM树上。
在这里我们可以用上,如图:
我们通过把 WXML 转化为数据,通过 Native 进行转发,来实现逻辑层和渲染层的交互和通信。而这样完整的一套框架,基本上都是通过小程序的基础库来完成的。
小程序的基础库是 JavaScript 编写的,它可以被注入到渲染层和逻辑层运行。主要用于:
由于小程序的渲染层和逻辑层是两个线程管理,两个线程各自注入了基础库。小程序的基础库不会被打包在某个小程序的代码包里边,它会被提前内置在微信客户端。这样可以:
Exparser 框架
Exparser 是微信小程序的组件组织框架,内置在小程序基础库中,为小程序的各种组件提供基础的支持。小程序内的所有组件,包括内置组件和自定义组件,都由 Exparser 组织管理。Exparser 特点包括:
关于基础库和 Exparser 框架,更多的也可以参考:《小程序开发指南》
本文转载自:https://godbasin.github.io,如有侵权,请联系作者。