关于uni-app:uniapp微信小程序React-Native跨端原理初探

4次阅读

共计 11107 个字符,预计需要花费 28 分钟才能阅读完成。

文章内容

  1. 以官网文档为根底,对 uni-app 的根底框架(逻辑层、渲染层)、组件、API 进行简略地剖析
  2. 以官网文档为根底,对 微信小程序 框架(逻辑层、视图层)、运行时进行简略地剖析
  3. 以官网文档为根底,对 React Native 旧架构和新架构进行简略地剖析

1. uni-app 编译

  • 在 web 平台,将.vue 文件编译为 js 代码。与一般的 vue cli 我的项目相似
  • 在微信小程序平台,编译器将.vue 文件拆分生成 wxml、wxss、js 等代码
  • 在 app 平台,将.vue 文件编译为 js 代码。进一步,如果波及 uts 代码:

    • 在 Android 平台,将.uts 文件编译为 kotlin 代码
    • 在 iOS 平台,将.uts 文件编译为 swift 代码

编译器分 vue2 版和 vue3 版

  • vue2 版:基于 webpack 实现
  • vue3 版:基于 Vite 实现,性能更快

编译器反对条件编译,即能够指定某局部代码只编译到特定的终端平台。从而将专用和个性化交融在一个工程中。

2. uni-app 运行时 runtime

2.1 根底框架

  • 在 web 和小程序上,不须要 uni-app 提供 js 引擎和排版引擎,间接应用浏览器和小程序的即可。但 app 上须要 uni-app 提供
  • App 的 js 引擎:App-Android 上,uni-app 的 js 引擎是 v8,App-iOS 是 jscore
  • App 的渲染引擎:同时提供了 2 套渲染引擎,.vue 页面文件由 webview 渲染,原理与小程序雷同;.nvue 页面文件由原生渲染,原理与 react native 雷同。开发者能够依据须要自主抉择渲染引擎。

uni-app App 端内置了一个基于 weex 改良的原生渲染引擎,提供了原生渲染能力

  • 在 App 端,如果应用 vue 页面,则应用 webview 渲染
  • 如果应用 nvue 页面(native vue 的缩写),则应用原生渲染
  • 一个 App 中能够同时应用两种页面,比方首页应用 nvue,二级页应用 vue 页面,hello uni-app 示例就是如此

尽管 nvue 也能够多端编译,输入 H5 和小程序,但 nvue 的 css 写法受限,所以如果你不开发 App,那么不须要应用 nvue。

2.1.1 逻辑层和渲染层拆散

在 web 平台,逻辑层(js)和渲染层(html、css),都运行在对立的 webview 里。
但在小程序和 app 端,逻辑层和渲染层被拆散了。

拆散的外围起因是性能。过来很多开发者吐槽基于 webview 的 app 性能不佳,很大起因是 js 运算和界面渲染抢资源导致的卡顿。

不论小程序还是 app,逻辑层都独立为了独自的 js 引擎,渲染层依然是 webview

app 上也反对纯原生渲染,应用.nvue 文件

2.1.2 逻辑层详解

逻辑层是运行在一个独立的 jscore 里的,它不依赖于本机的 webview,所以一方面它没有浏览器兼容问题,能够在 Android4.4 上跑 es6 代码,另一方面,它无奈运行 window、document、navigator、localstorage 等浏览器专用的 js API。

jscore 就是一个规范 js 引擎,规范 js 是能够失常运行的,比方 if、for、各种字符串、日期解决等。js 和浏览器的区别要留神辨别开来。

  • 所谓浏览器的 js 引擎,就是 jscore 或 v8 的根底上新增了一批浏览器专用 API,比方 dom;
  • node.js 引擎,则是 v8 根底上补充一些电脑专用 API,比方本地 io;
  • 那么 uni-app 的 App 端和小程序端的 js 引擎,其实是在 jscore 上补充了一批手机端罕用的 JS API,比方扫码。

2.1.3 渲染层详解

h5 和小程序平台,以及 app-vue,视图层是 webview,即 .vue 文件都会被渲染为WebView

app-nvue 的视图层是基于 weex 革新的原生渲染视图,即 .nvue 文件会被革新为 APP 原生组件

兼容性

在 iOS 上,只能应用 iOS 提供的 Webview(默认是 WKWebview)。它有肯定的浏览器兼容问题,iOS 版本不同,它的体现有轻微差别(个别可疏忽)。

在 Android 上,小程序大多自带了一个几十 M 的 chromium webview,而 App 端没方法带这么大体积的三方包,因而 uni-app 默认应用了 Android system webview,这个零碎 webview 追随手机不同而有差别

在 Android 上,App 端也反对应用腾讯 X5 引擎,这样就对立版本,尽可能减少兼容性问题

2.1.4 逻辑层和渲染层小结

逻辑层: js 根本没有不同手机的兼容问题(因为 js 引擎自带了)

渲染层: 在 app-vue 上应用零碎 webview 时会有手机浏览器的 css 兼容问题。此时或者不要用太新的 css 语法,或者集成腾讯 x5 引擎。

2.1.5 逻辑层和渲染层拆散的利与弊

逻辑层和视图层拆散,益处是 js 运算不卡渲染,最简略间接的感触就是:窗体动画稳。

如果开发者应用过 App,应该有概念,webview 新窗体一边做进入动画,一边本身渲染,很容易卡动画。而 uni-app 则无需写预载代码,新窗体渲染快且动画稳固。

然而两层拆散也带来一个害处,这两层相互通信,其实是有损耗的。

iOS 还好,但 Android 低端机上,每次通信都要耗时几十毫秒。平时看不出来影响,但有几个场景体现显著:

  1. 间断高帧率绘制 canvas 动画,会发现还不如 webview 外部绘制晦涩
  2. 视图层滚动、跟手操作,不停反馈给逻辑层,js 再解决逻辑并告诉视图层做对应更新。此时会发现交互不跟手或卡顿

不论小程序还是 app,不论 app-vue 还是 app-nvue,都有这个两层通信损耗的问题。

2.1.6 逻辑层和渲染层拆散后进行的性能晋升办法

在 webview 中,提供了一种运行于视图层的专属 js,微信叫做 wxs。uni-app 反对把 wxs 编译到微信小程序、App 和 H5 中,而且在 wxs 的根底上进行加强:

  • 微信里对 wxs 限度较多,只能实现无限的性能。
  • app 端提供了更弱小的 renderjs,并兼容到 H5 平台,比方 canvas 动画,微信的 canvas 无奈通过 wxs 操作,js 不停绘制 canvas 动画因通信折损而无奈晦涩。uni-app 的 app-vue 里的 canvas 对象设计在 webview 视图层的,通过 renderjs 能够在视图层间接操作 canvas 动画,将不再有通信折损,实现更晦涩的成果

在原生渲染的视图层(app-nvue),逻辑层和视图层的折损一样存在。包含 react native 也有这个问题,weex 提供了一套 bindingx 机制,能够在 js 里一次性传一个表达式给原生层,由原生层解析后依据指令操作原生的视图层,防止重复跨层通信。这个技术在 uni-app 里也能够应用。

bindingx 作为一种表达式,它的性能不迭 js 弱小,但手势监听、动画还是能够实现的,比方 uni ui 的 swiperAction 组件在 app-nvue 下运行时会主动启用 bindingx,以实现晦涩跟手。

2.2 组件

为了升高开发者的学习老本,uni-app 的内置根底组件命名标准与小程序基本相同。

runtime 中包含的组件只有根底组件,如 <view>、<button> 等。为了缩小包体积,扩大组件不蕴含在 uni-app 的 runtime 中,而是下载到用户的我的项目代码中(这些组件都是 vue 组件),让用户本人按需应用这些扩大组件

在小程序端,uni-app 根底组件会间接本义为小程序本人的内置组件。在小程序的 runtime 中不占体积。在 web 和 android、iOS 端,这几十个组件都在 uni-app 的 runtime 中,会占用肯定体积,相当于内置了一套 ui 库。

2.3 API

次要分为:

  • 小程序平台:uni 对象会转为小程序的自有对象,比方在微信小程序平台,编写 uni.request 等同于 wx.request。那么所有 wx. 的 API 都能够这样应用。
  • web 平台:window、dom 等浏览器专用 API 仍能够应用
  • app 平台:除了 uni. 的 API,还能够应用 plus. 的 API、Native.js,以及通过 uts 编写原生插件,或者应用 java 和 objectC 编写原生插件。这些原生插件调用 os 的 API 并封装给 js 应用。

uni-app 不限度各端原生平台的 API 调用。开发者能够在 uni-app 框架中无限度的调用该平台所有能应用的 API。即,

  • 在小程序平台,小程序的所有 API 都能够应用;
  • 在 web 平台,浏览器的所有 API 都可应用;
  • 在 iOS 和 Android 平台,os 的所有 API 都能够应用。

在下面的 2.1 根底框架 的剖析中,咱们晓得
App 的渲染提供了 2 套渲染引擎:

  • .vue 页面文件由 webview 渲染,原理与小程序雷同
  • .nvue 页面文件由原生渲染,原理与 react native 雷同

接下来咱们将针对小程序和 react native 的原理开展剖析


3. 微信小程序底层原理

3.1 框架

整个小程序框架零碎分为两局部:逻辑层(App Service)和 视图层(View)。小程序提供了本人的视图层描述语言 WXMLWXSS,以及基于 JavaScript 的逻辑层框架,并在视图层与逻辑层间提供了数据传输和事件零碎,让开发者可能专一于数据与逻辑。

小程序采纳 AppService 和 WebView 的双线程模型,渲染层的界面应用 WebView 进行渲染;逻辑层采纳 JSCore 运行 JavaScript 代码
基于 WebView 和原生控件混合渲染的形式,小程序还优化扩大了 Web 的根底能力,保障了在挪动端上有良好的性能和用户体验

Skyline 渲染引擎 Beta

Skyline 渲染引擎理解下即可,目前还处于测试阶段,本文还是将重点放在 WebView 模式下

Web 技术至今已有 30 多年历史,作为一款弱小的渲染引擎,它有着良好的兼容性和丰盛的个性。只管各大厂商在一直优化 Web 性能,但因为其沉重的历史包袱和简单的渲染流程,使得 Web 在挪动端的体现与原生利用仍有肯定差距。
为了进一步优化小程序性能,提供更为靠近原生的用户体验,微信小程序在 WebView 渲染之外新增了一个渲染引擎 Skyline,其应用更精简高效的渲染管线,并带来诸多加强个性,让 Skyline 领有更靠近原生渲染的性能体验。

在 Skyline 环境下,Skyline 创立了一条渲染线程来负责 Layout, Composite 和 Paint 等渲染工作,并在 AppService 中划出一个独立的上下文,来运行之前 WebView 承当的 JS 逻辑、DOM 树创立等逻辑。这种新的架构相比原有的 WebView 架构,有以下特点:

  • 界面更不容易被逻辑阻塞,进一步缩小卡顿
  • 无需为每个页面新建一个 JS 引擎实例(WebView),缩小了内存、工夫开销
  • 框架能够在页面之间共享更多的资源,进一步缩小运行时内存、工夫开销
  • 框架的代码之间无需再通过 JSBridge 进行数据交换,缩小了大量通信工夫开销

Skyline 渲染引擎 能很好地放弃和原有架构的兼容性,基于 WebView 环境的小程序代码基本上无需任何改变即可间接在新的架构下运行。然而 WXS 被移到 AppService 中,尽管逻辑自身无需改变,但询问页面信息等接口会变为异步,效率也可能有所降落;为此,咱们同时推出了新的 Worklet 机制,用以高性能地构建各种简单的动画成果。

新的渲染流程如下图所示:

3.1.1 逻辑层

小程序开发框架的逻辑层应用 JavaScript 引擎为小程序提供开发 JavaScript 代码的运行环境以及微信小程序的特有性能。
逻辑层将数据进行解决后发送给视图层,同时承受视图层的事件反馈。

开发者写的所有代码最终将会打包成一份 JavaScript 文件,并在小程序启动的时候运行,直到小程序销毁。

JavaScript 的根底上,微信小程序减少了一些性能,以不便小程序的开发:

  • 减少 AppPage 办法,进行程序注册和页面注册。
  • 减少 getAppgetCurrentPages 办法,别离用来获取 App 实例和以后页面栈。
  • 提供丰盛的 API,如微信用户数据,扫一扫,领取等微信特有能力。
  • 提供模块化能力,每个页面有独立的作用域。

留神:小程序框架的逻辑层并非运行在浏览器中,因而 JavaScript 在 web 中一些能力都无奈应用,如 window,document 等。

3.1.2 视图层

框架的视图层由 WXML 与 WXSS 编写,由组件来进行展现。
将逻辑层的数据反映成视图,同时将视图层的事件发送给逻辑层。

  • WXML(WeiXin Markup language) 用于形容页面的构造。
  • WXS(WeiXin Script) 是小程序的一套脚本语言,联合 WXML,能够构建出页面的构造。
  • WXSS(WeiXin Style Sheet) 用于形容页面的款式。
  • 组件 (Component) 是视图的根本组成单元。

3.1.3 双线程模型架构

小程序的逻辑层和渲染层是离开的两个线程。在渲染层,宿主环境会把 WXML 转化成对应的 JS 对象,在逻辑层产生数据变更的时候,咱们须要通过宿主环境提供的 setData 办法把数据从逻辑层传递到渲染层,再通过比照前后差别,把差别利用在原来的 Dom 树上,渲染出正确的 UI 界面

因为 WebView 的 JS 逻辑、DOM 树创立、CSS 解析、款式计算、Layout、Paint (Composite) 都产生在同一线程。在 WebView 上执行过多的 JS 逻辑可能阻塞渲染,导致界面卡顿。

小程序逻辑层和渲染层的通信会由 Native(微信客户端)做直达,逻辑层发送网络申请也经由 Native 转发。

为什么要应用Hybrid 技术来渲染微信小程序呢?

一般来说,渲染界面的技术有三种:

  1. 用纯客户端原生技术来渲染
  2. 用纯 Web 技术来渲染
  3. 介于客户端原生技术与 Web 技术之间的,相互联合各自特点的技术(上面统称 Hybrid 技术)来渲染

因为小程序的宿主是微信,所以不太可能用纯客户端原生技术来编写小程序。如果这么做,那小程序代码须要与微信代码一起编包,追随微信发版本,这种形式跟开发节奏必然都是不对的。因而,微信小程序须要像 Web 技术那样,有一份随时可更新的资源包放在云端,通过下载到本地,动静执行后即可渲染出界面。

然而,如果微信小程序用纯 Web 技术来渲染小程序,在一些有简单交互的页面上可能会面临一些性能问题,这是因为在 Web 技术中,UI 渲染跟 JavaScript 的脚本执行都在一个单线程中执行,这就容易导致一些逻辑工作抢占 UI 渲染的资源。

因而,最终抉择了两者联合起来的 Hybrid 技术来渲染小程序。

Hybrid 技术在业界过来几年里演变过数种技术计划:典型的如晚期的 PhoneGap,还有近几年风行的 React Native(下称 RN),还有像微信网页里的 JS-SDK 这种轻量级的利用

为什么要不应用 React Native 这样技术作为微信小程序的技术选型呢?

微信小程序最终没有抉择类 RN 作为微信小程序的技术选型,那是因为:

  1. RN 所反对的款式是 CSS 的子集,会满足不了 Web 开发者日渐增长的需要,而对 RN 的革新具备不小的老本和危险。
  2. RN 现有能力下还存在的一些不稳固问题,比方性能、Bug 等。RN 是把渲染工作全都交由客户端原生渲染,实际上一些简略的界面元素应用 Web 技术渲染齐全能胜任,并且十分稳固。
  3. RN 存在一些不可预期的因素,比方近期就呈现了许可协定问题。

因而微信小程序最终抉择了相似于微信 JSSDK 这样的 Hybrid 技术,即界面次要由成熟的 Web 技术渲染,辅之以大量的接口提供丰盛的客户端原生能力:

  • 每个小程序页面都是用不同的 WebView 去渲染,这样能够提供更好的交互体验,更贴近原生体验,也防止了单个 WebView 的工作过于沉重
  • 界面渲染定义了一套内置组件以对立体验,并且提供一些根底和通用的能力
  • 内置组件有一部分较简单组件是用客户端原生渲染的,以提供更好的性能

3.1.4 组件零碎

视图层的组件零碎

小程序的视图是在 WebView 里渲染的,那搭建视图的形式天然就须要用到 HTML 语言。如果咱们间接提供 HTML 的能力,那后面章节所介绍的为解决管控与平安而建设的双线程模型就成为陈设了。开发者能够利用 A 标签实现跳转到其它在线网页,也能够动静执行 JavaScript 等。除管控与平安外,还有一些的不足之处:

  • 标签泛滥,减少了解老本;
  • 接口底层,不利于疾速开发;
  • 能力无限,会限度小程序的表现形式。

因而,微信小程序设计一套组件框架——Exparser。
基于这个框架,内置了一套组件,以涵盖小程序的根底性能,便于开发者疾速搭建出任何界面。同时也提供了自定义组件的能力,开发者能够自行扩大更多的组件,以实现代码复用。

3.1.5 原生组件

在内置组件中,有一些组件较为非凡,它们并不齐全在 Exparser 的渲染体系下,而是由客户端原生参加组件的渲染,这类组件咱们称为“原生组件”,这也是小程序 Hybrid 技术的一个利用。
引入原生组件次要有 3 个益处:

  1. 扩大 Web 的能力。比方像输入框组件(input, textarea)有更好地管制键盘的能力。
  2. 体验更好,同时也加重 WebView 的渲染工作。比方像地图组件(map)这类较简单的组件,其渲染工作不占用 WebView 线程,而交给更高效的客户端原生解决。
  3. 绕过 setData、数据通信和重渲染流程,使渲染性能更好。比方像画布组件(canvas)可间接用一套丰盛的绘图接口进行绘制。

罕用的原生组件有:video、map、canvas、picker

交互比较复杂的原生组件都会提供“context”,用于间接操作组件。以 canvas 为例,小程序提供了 wx.createCanvasContext 办法来创立 canvas 的 context。这是一个能够用于操作 canvas 的对象,对象下提供了很多绘图的办法,如“setFillStyle”办法能够设置填充款式,“fillRect”办法用于绘制矩形

原生组件脱离在 WebView 渲染流程外,这带来了一些限度。最次要的限度是一些 CSS 款式无奈利用于原生组件,例如,不能在父级节点应用 overflow:hidden 来裁剪原生组件的显示区域;不能应用 transformrotate 让原生组件产生旋转等

3.2 运行时

微信小程序运行在多种平台上:iOS/iPadOS 微信客户端、Android 微信客户端、Windows PC 微信客户端、Mac 微信客户端、小程序硬件框架和用于调试的微信开发者工具等。

不同运行环境下,脚本执行环境以及用于组件渲染的环境是不同的,性能体现也存在差别:

  • 在 iOS、iPadOS 和 Mac OS 上,小程序逻辑层的 JavaScript 代码运行在 JavaScriptCore 中,视图层是由 WKWebView 来渲染的,环境有 iOS 14、iPad OS 14、Mac OS 11.4 等;
  • 在 Android 上,小程序逻辑层的 JavaScript 代码运行在 V8 中,视图层是由基于 Mobile Chromium 内核的微信自研 XWeb 引擎来渲染的;
  • 在 Windows 上,小程序逻辑层 JavaScript 和视图层都是用 Chromium 内核;
  • 在 开发工具上,小程序逻辑层的 JavaScript 代码是运行在 NW.js 中,视图层是由 Chromium Webview 来渲染的。

3.2.1 JavaScript 反对状况

  • 小程序中不反对动静执行 JS 代码,即应用 eval 执行 JS 代码或者应用 new Function 创立函数
  • 规范 ECMAScript 反对,微信小程序内置了一份 core-jsPolyfill。core-js 能够将平台环境缺失的规范 API 补齐。

须要留神的是,平台对 ECMAScript 语法的反对差别无奈抹平,当你须要应用一些高级语法时,如 async/await 时,则须要借助 代码转换工具 来反对这些语法。

  • 无奈反对一些无奈被 Polyfill 的 API,比方Proxy 对象

注:因为实现起因与 iOS JavaScriptCore 限度,iOS 环境下的 Promise 是一个应用 setTimeout 模仿的 Polyfill。这意味着 Promise 触发的工作为一般工作,而非微工作,进而导致 在 iOS 下的 Promise 时序会和规范存在差别

3.2.2 小程序的运行机制

  • 冷启动:如果用户首次关上,或小程序销毁后被用户再次关上,此时小程序须要从新加载启动,即冷启动。

如果用户曾经关上过某小程序,而后在肯定工夫内再次关上该小程序,此时小程序并未被销毁,只是从后盾状态进入前台状态,这个过程就是热启动。
从小程序生命周期的角度来看,咱们个别讲的「启动」专指冷启动,热启动个别被称为后盾切前台。

  • 小程序启动后,界面被展现给用户,此时小程序处于「前台」状态。
  • 当用户「敞开」小程序时,小程序并没有真正被敞开,而是进入了「后盾」状态,此时小程序还能够短暂运行一小段时间,但局部 API 的应用会受到限制。

切后盾的形式包含但不限于以下几种:

  • 点击右上角胶囊按钮来到小程序
  • iOS 从屏幕左侧右滑来到小程序
  • 安卓点击返回键来到小程序
  • 小程序前台运行时间接把微信切后盾(手势或 Home 键)
  • 小程序前台运行时间接锁屏
  • 小程序进入「后盾」状态一段时间后(目前是 5 秒),微信会进行小程序 JS 线程的执行,小程序进入「挂起」状态。此时小程序的内存状态会被保留,但开发者代码执行会进行,事件和接口回调会在小程序再次进入「前台」时触发。

当开发者应用了后盾音乐播放、后盾地理位置等能力时,小程序能够在「后盾」继续运行,不会进入到「挂起」状态

  • 小程序销毁:如果用户很久没有应用小程序,或者系统资源缓和,小程序会被「销毁」,即齐全终止运行。

具体而言包含以下几种情景:

  • 当小程序进入后盾并被「挂起」后,如果很长时间(目前是 30 分钟)都未再次进入前台,小程序会被销毁。
  • 当小程序占用系统资源过高,可能会被零碎销毁或被微信客户端被动回收。

4. React Native 原理

从 0.68 版本开始,React Native 提供了新架构,它为开发者提供了构建高性能和响应式利用的新性能。

4.1 旧架构

上面架构图来自 Deep dive into React Native’s New Architecture

4.1.1 三线程

React Native 次要有 3 个线程:

  • JavaScript Thread:Metro(打包工具)将 React 源码打包成 JS Bundle 文件,而后传入 JavaScriptCore 引擎进行执行
  • Native/UI Thread:负责原生 UI 渲染 Native UI 和调用原生 API 能力Navite Module(比方蓝牙、照相机等)
  • Shadow Thread:创立 Shadow Tree 模仿React 构造树,用于在将元素渲染到主机屏幕之前计算元素的布局

4.1.2 Bridge

JS ThreadUI Thread 之间的通信称为 Bridge,通过Bridge 发送数据时,有几个特点:

  • 批处理:对 Native 调用进行排队,批量解决
  • 序列化:通过 JSON 格局来传递音讯,每次都要经验序列化和反序列化
  • 异步:音讯队列是异步的

即通过 Bridge 发送数据时,必须对其进行批处理(优化)并序列化为 JSON

4.1.3 JavaScriptCore

JavaScriptCore 是一个 JS 引擎,IOS 零碎自带了该引擎。为了对立 Android 和 IOS 应用同一个 JavaScriptCore,React Native 会将 JavaScriptCore 和 app 打包在一起,

  • 从 React Native 0.70 版本开始,React Native 会默认应用 Hermes 引擎,它是专门为 React Native 而优化的一个旧式开源 JavaScript 引擎。
  • 如果 Hermes 被禁用或是较早的 React Native 版本,则会应用 JavaScriptCore,也就是 Safari 所应用的 JavaScript 引擎。然而在 iOS 上 JavaScriptCore 并没有应用即时编译技术(JIT),因为在 iOS 中利用无权领有可写可执行的内存页(因而无奈动静生成代码)。
  • 在应用 Chrome 调试时,所有的 JavaScript 代码都运行在 Chrome 中,并且通过 WebSocket 与原生代码通信。此时的运行环境是 V8 引擎。(社区也有提供能够在生产环境中应用的 react-native-v8)

从 0.68 版本开始,React Native 提供了新架构,它为开发者提供了构建高性能和响应式利用的新性能。因而从 0.70 版本开始,会应用 Hermes 引擎

4.1.4 Yoga

它是布局引擎的名称,用于计算用户屏幕的 UI 元素的地位

4.1.5 渲染流程浅析

  1. 布局应用 React 编写,转化为 Virtual DOM Tree 后,JavaScript Thread应用 Bridge 发送序列化的 JSON 数据给Native/UI Thread,通知它如何创立或者更新原生 UI
  2. 这个时候 Native/UI Thread 会将数据发送给 Shadow ThreadShadow Thread 通过保护一个 Shadow TreeShadow Tree 能够了解为是 Virtual DOM TreeNative 的映射,领有和 Virtual DOM Tree 雷同的树形层级关系)来计算 Virtual DOM TreeNative 页面的理论布局
  3. 计算实现后 Shadow Thread 返回数据异步告诉 Native/UI Thread 进行创立或者更新原生 UI

React Native 不适宜绘制特地简单的界面以及简单的动画,成果比不上原生的成果

4.2 新的架构

从 0.68 版本开始,React Native 提供了新架构,它为开发者提供了构建高性能和响应式利用的新性能。

上面架构图来自 Deep dive into React Native’s New Architecture

4.2.1 旧架构的问题

旧的架构已经通过应用一个叫做桥(Bridge)的组件将所有必须从 JS 层传递到本地层的数据序列化来工作。桥能够被设想成一条总线,生产者层为消费者层发送一些数据。消费者能够读取数据,将其反序列化并执行所需的操作。
桥有一些固有的限度:

  • 它是异步的:某个层将数据提交给桥,再异步地 ” 期待 ” 另一个层来解决它们,即便有时候这并不是真正必要的。
  • 它是单线程的:JS 是单线程的,因而产生在 JS 中的计算也必须在单线程上进行。
  • 它带来了额定的开销:每当一个层必须应用另一个层时,它就必须序列化一些数据。另一层则必须对其进行反序列化。这里抉择的格局是 JSON,因为它的简略性和人的可读性,但只管是轻量级的,它也是有开销的。

4.4.2 新架构的改良

新架构放弃了 ” 桥 ” 的概念,转而采纳另一种通信机制:JavaScript 接口(JSI)。JSI 是一个接口,容许 JavaScript 对象持有对 C++ 的援用,反之亦然。

一旦一个对象领有另一个对象的援用,它就能够间接调用该对象的办法。例如一个 C++ 对象当初能够间接调用一个 JavaScript 对象在 JavaScript 环境中执行一个办法,反之亦然。

这个想法能够带来几个益处:

  • 同步执行:当初能够同步执行那些原本就不应该是异步的函数。
  • 并发:能够在 JavaScript 中调用在不同线程上执行的函数。
  • 更低的开销:新架构不须要再对数据进行序列化 / 反序列化,因而能够防止序列化的开销。
  • 代码共享:通过引入 C++,当初有可能形象出所有与平台无关的代码,并在平台之间轻松共享它。
  • 类型平安:为了确保 JS 能够正确调用 C++ 对象的办法,反之亦然,因而减少了一层主动生成的代码。这些代码必须通过 Flow 或 TypeScript 类型化的 JS 标准来生成。

参考文章

  1. 跨端框架一些原理剖析
  2. React-Native — 原理探索
  3. 微信小程序官网文档
  4. uni-app 官网文档
  5. React Native 架构比照
  6. React Native 技术详解 (一) – 意识它
  7. Deep dive into React Native’s New Architecture
正文完
 0