用户
 找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,登录网站

小程序社区 首页 教程 实战教程 查看内容

各小程序框架实现思路学习记录

Rolan 2020-11-17 10:39

小程序,是双线程工作的。它分为逻辑层跟视图层。他们通过线程通信,共同完成视图的完整呈现和交互。

小程序

已知,网页是单线程工作的,即是渲染进程在工作时,假如 JavaScript 引擎 执行 JavaScript 代码时,渲染进程会将控制权交予 JavaScript 引擎,不会两个进程同时在工作。因为,JavaScript 引擎 可能会操作DOM,所以,为了排除冲突,确保渲染正确,网页是单线程工作的。

但是,小程序,是双线程工作的。它分为逻辑层视图层。他们通过线程通信,共同完成视图的完整呈现和交互。此外,小程序不提供操作视图层的元素的方法,所以它无法像网页那样用 JavaScript 去操作 DOM 元素去实现更新。

引自:小程序的运行环境

各平台脚本执行环境以及用于渲染非原生组件的环境是各不相同的:

  • 在 iOS 上,小程序逻辑层的 javascript 代码运行在 JavaScriptCore 中,视图层是由 WKWebView 来渲染的,环境有 iOS 12、iOS 13 等;

  • 在 Android 上,小程序逻辑层的 javascript 代码运行在 V8 中,视图层是由自研 XWeb 引擎基于 Mobile Chrome 内核来渲染的;

  • 在 开发工具上,小程序逻辑层的 javascript 代码是运行在 NW.js 中,视图层是由 Chromium Webview 来渲染的。

视图层的实现是 webView ,但这是一个定制 webView ,它不能运行 JavaScript ,且内容也不是 html

那么,小程序为什么要实现双线程工作呢?官方回答如下:

  • 快速的加载
  • 更强大的能力
  • 原生的体验
  • 易用且安全的微信数据开放
  • 高效和简单的开发

但,这个见仁见智吧。

Mpvue

在小程序整出一套 wxml wxss wxs 的组合拳时,其实是在给开发者增加负担。那有没有一种方案,是用自己熟悉的框架的语法去写,但是产出却是小程序呢?办法总是有的,Mpvue 先行一步。其实 vue runtime 并不涉及 DOM 的修改,它就是一整套的 JavaScript 方法,可以愉快地运行在小程序的逻辑层。所以 Mpvue 复制了一套 Vue 库出来改造一下去实现这个伟大的目标。

实现原理如下:

// 这是 Vue 的实现
// template -> AST -> render -> vnode -> patch -> DOM
//                      ^					
//                     /
//                    /
// js ---------> new Vue()

// 这是 Mpvue
// template -> AST -> render -> vnode -> patch -/-> DOM
//                      ^		   |
//                     /		   |
//                    /			   V
// js ---------> new Vue()	    ---> setData
//                   \		   /
//                    \-> page() /
// 												
复制代码

在创建 Vue 示例的时候,调用 page 方法,经过 Vue 处理后并不patchDOM去渲染,而是通过 setData 去更新小程序实例上的数据,从而更新小程序的视图(因为小程序分了逻辑层和视图层,所以小程序并没有提供操作小程序节点的 API 方法)。

引自:【2万字长文】深入浅出主流的几款小程序跨端框架原理

小程序平台还规定,要在小程序页面中调用 Page() 方法生成一个 page 实例, Page() 方法是小程序官方提供的 API。(解答为什么需要调用 page 方法)

此外,Vue模板转小程序模板,生命周期对齐,事件处理等暂且不说。大体的实现原理就这些。

总结:

类Vue的小程序框架实现原理关键点:

  1. 实例化时,调用 page 方法
  2. 更改Vue流程,使用 setData 来替代 DOM 操作
  3. Vue模板转小程序模板,生命周期对齐,事件处理等

Taro 1 & 2

ReactVue 难处理的点在于,React 开发是非模板化的,使用了 jsx ,导致它太灵活了,不好圈定范围去转化为小程序的模板(我们知道模板转化主要是靠AST来完成的,有限的范围可以更好地处理)。

Taro 还是啃下了这块硬骨头,当然,不是那么容易和愉快。限制很多,开发只是类 React

Taro 通过穷举法将类 React 的组件和元素,通过AST转化为小程序的模板,加上不管是类Vue还是类React的小程序框架都要做的事情:生命周期对齐,事件处理等,就这样,啃下了这块硬骨头。

总结:

主要是靠 AST 穷举完成模板转化(核心),除了拥有了 React 开发时的爽度外,React 的其他优势无法利用。但无论如何也是值得鼓励和称赞。

Remax & Taro Next

如同 Mpvue 先行者,RemaxReact 类小程序框架也迈出了重要的一步。

Remax 的口号是,使用真正的、完整的 React 来开发小程序

它是怎么达成这个目标的呢?请看下面的流程分析:

// Remax 分析
// ----------------------------------------------------
// --------------| react reconciliation |--------------
// -------------------------|--------------------------
// -------------------------V--------------------------
// ---------------| vNode and Effect List |------------
// -------------------------|--------------------------
// -------------------------V--------------------------
// ----------------| Remax vNode (json) |--------------
// -------------------------|--------------------------
// -------------------------V--------------------------
// --------------| miniProgrom setData |---------------
// -------------------------|--------------------------
// -------------------------V--------------------------
// ----------------| miniProgrom data |----------------
// -------------------------|--------------------------
// -------------------------V--------------------------
// -------------------| base.wxml |--------------------
// -------------------------|--------------------------
// ---------------------( 递归遍历 )---------------------
// -------------------------|--------------------------
// -------------------------V--------------------------
// --------------------| 页面 / 组件 |-------------------
复制代码

Remax 可以分为两个部分,一个是 react runtime ,包含 react 的除 render 之外的核心内容;另一部分就是 Remax 实现的渲染器。

引自:Remax 实现原理

Remax 的运行时本质是一个通过 react-reconciler 实现的一个小程序端的渲染器。

直白点,**Remax的核心大约是 React reconciliation + Remax 渲染器 + base.wxml **。

解释一下这:

  1. React reconciliation 负责更新节点和更新时机,产出是 vnode
  2. Remax 渲染器,将以上产出的 vnode 从原本应该渲染为DOM 的操作改为生成/更新自身 vnode 树(此 vnodereactvnode 不同,是 Remax 创建的 vnode),产出是 Remax vnode
  3. 调用 setData 方法,让小程序更新数据,从而将 Remax vnode 传递到小程序中,然后小程序根据 database.wxml递归渲染出页面来。

总结:

Remax Taro Next 实现思路是一致的,真正地让 React 运行时在小程序的逻辑层跑起来了,从而拥有比较完整的React开发体验

实现的基础条件是,小程序的 template 支持动态递归渲染

实现核心在于,Remax 渲染器将 React 运行时产出的 vnode 转化为 Remax vnode,从而拥有一颗完整的节点树。然后数据 + template 动态递归渲染,渲染出页面来

类 Vue 小程序框架和拥有完整体验的类 React 小程序框架的实现思路对比

从上文可以看到,类 Vue 小程序框架的实现思路是 **Vue 运行时 + AST 转化小程序模板 **。

拥有完整体验的类 React 小程序框架实现的思路是 React 运行时 + 运行在内存中的由各个框架维护的 vnode 树(非 VDOM 的 vnode) + 静态模板

看起来,类 Vue 小程序框架的实现思路更胜一层,但其需要对Vue框架进行一定的改造,所以会比较依赖 Vue

拥有完整体验的类 React 小程序框架,有 React 的完整开发体验(这也很重要),但无法利用 React 的调度,是递归地渲染(这和 React 以前无调度版本很相似)。且有一个必要的基础条件,就是微信小程序的 template 支持动态递归(这是 Remax 的地基)。

鲜花
鲜花
鸡蛋
鸡蛋
分享至 : QQ空间
收藏