写在前面

上一篇(React Native 架构一览)从设计、线程模型等方面介绍了 React Native 的现有架构,本篇将分析这种架构的局限性,以及 React Native 正在进行的架构升级计划

一.现有架构的局限性

最初的设计也带来了一些限制:

  • 异步:无法将 JavaScript 逻辑直接与许多需要同步答案的 Native API 集成

  • 批处理:很难让 React Native 应用调用 Native 实现的函数

  • 可序列化:存在不必要的 copy,而不是直接共享内存

这些问题在 Native + React Native 的混合应用中尤其突出:

For apps that are entirely built in React Native, these restrictions are usually bearable. But for apps with complex integration between React Native and existing app code, they are frustrating.

二.架构升级计划

因此,2018 年 6 月提出大规模重构的计划,目的是更好地支持混合应用:

We're working on a large-scale rearchitecture of React Native to make the framework more flexible and integrate better with native infrastructure in hybrid JavaScript/native apps.

具体的,有 3 点重大改动:

  • 线程模型:允许在任意线程中同步调用 JavaScript执行高优先级的更新,UI 更新不再非要跨 3 个线程才能进行

  • React:支持 React 16+的新特性,包括async rendering、Data Fetching 等等

  • Bridge:精简优化,允许 Native 与 JavaScript 之间的直接调用

支持同步调用让之前很难实现的一些东西成为了可能,例如跨语言的调用栈追踪

对应到架构图中,相当于对每一层进行单独优化:

  • React 层:增强 JavaScript 类型安全,并支持 React 16+新特性

  • JavaScript 层:引入 JSI,允许替换不同的 JavaScript 引擎

  • Bridge 层:划分成 Fabric 和 TurboModules 两部分,分别负责 UI 渲染与 Native 模块

  • Native 层:精简核心模块,将非核心部分拆分出去作为社区模块独立更新维护

初步估计,这些重构工作预期在 2019 年底或 2020 年初完成:

It’s likely this massive piece of work will reach its conclusion around Q4 2019 or Q1 2020, but there are no confirmed dates.

P.S.目前(2019/9/8)除已完成的 JSI 外,其余重构计划仍在进行中,具体见The New React Native Architecture Explained: Part Four

三.增强 JavaScript 类型安全

主要变化在于,提供 CodeGen 工具来保证消息通信的类型安全,以解决 JavaScript 与 Native 通信中被广为诟病的 Bridge API 数据类型问题:

We also experienced many issues in which the types coming from JavaScript were unexpected. For example, integers were often wrapped by strings, an issue that isn’t realized until it is passed over a bridge. To make matters worse, sometimes iOS will fail silently while Android will crash.

(摘自React Native at Airbnb: The Technology

另一方面,类型约束对通信性能也有一定帮助:

This automation will speed up the communication too, as it’s not necessary to validate the data every time.

四.引入 JSI

上层 JavaScript 代码需要一个运行时环境,在 React Native 中这个环境是 JSC(JavaScriptCore)。不同于之前直接将 JavaScript 代码输入给 JSC,新的架构中引入了一层 JSI(JavaScript Interface),作为 JSC 之上的抽象,用来屏蔽 JavaScript 引擎的差异,允许换用不同的 JavaScript 引擎(如最近推出的Hermes

更重要的,有了 JSI 之后,JavaScript 还能持有 C++对象的引用,并调用其方法:

By using JSI, JavaScript can hold reference to C++ Host Objects and invoke methods on them.

从而允许 JavaScript 与 Native 的直接调用,而不必通过跨线程消息通信,省去序列化/反序列化的成本,还能减轻 Bridge 的通信压力(如大量消息排队堵车)

同时JSI 所在的 C++层也可以作为复用 Native 代码的一种方式,拥有 Native 的天然支持:

  • Android:通过 JNI(Java Native Interface)调用 C 或 C++模块

  • iOS:Objective-C 默认支持

五.重构 Bridge 层

新的 Bridge 层被划分成 Fabric 和 TurboModules 两部分:

  • Fabric:负责管理 UI

  • TurboModules:负责与 Native 交互

Fabric 期望以更现代化的方式去实现 React Native 的渲染层,简化之前渲染流程中复杂跨线程交互(React -> Native -> Shadow Tree -> Native UI)。具体的,直接在 C++层创建 JavaScript 与 Native 共享的 Shadow Tree,并通过 JSI 层将 UI 操作接口暴露给 JavaScript,允许 JavaScript 直接控制高优先级的 UI 操作,甚至允许同步调用(应对列表快速滚动、页面切换、手势处理等场景)

之前所有 Native Modules(无论是否需要用到)都要在应用启动时进行初始化,因为 Native 不知道 JavaScript 将会调用哪些功能模块。而新的TurboModules 允许按需加载 Native 模块,并在模块初始化之后直接持有其引用,不再依靠消息通信来调用模块功能。因此,应用的启动时间也会有所提升

六.精简核心模块

理论上,React Native 应该是通用的,对平台无感知,这是能够支持WebWindows等不同平台的关键

虽然 Native 不在 React Native 的掌控中,无法垂直地深入优化,但可以进行横向的精简,将非核心的部分代码拆分出去作为社区模块,如 AsyncStorage、ImageStore、MaskedViewIOS、NetInfo 等等。一方面缩减包体积,另一方面也有利于这些模块的独立更新维护

参考资料

React Native 架构演进的更多相关文章

  1. React Native 架构一览

    一.架构设计 整体上分为三大块,Native.JavaScript 与 Bridge: Native 管理 UI 更新及交互,JavaScript 调用 Native 能力实现业务功能,Bridge ...

  2. 1000 千米高空俯瞰 React Native

    一.历史:React Native 从开始到现在 React Native 的定位是通过 React 构建原生 App: A framework for building native apps wi ...

  3. React Native开发 - 搭建React Native开发环境

    移动开发以前一般都是原生的语言来开发,Android开发是用Java语言,IOS的开发是Object-C或者Swift.那么对于开发一个App,至少需要两套代码.两个团队.对于公司来说,成本还是有的. ...

  4. reactNative-解决react native使用fetch函数 Network request failed 问题

    解决react native使用fetch函数Network request failed问题 最近公司新开发一个app, 用react native架构好后,用xcode模拟器打开app,对接登陆接 ...

  5. React Native For Android 架构初探

    版权声明:本文由王少鸣原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/171 来源:腾云阁 https://www.qclo ...

  6. React Native IOS ---基础环境搭建(前端架构师)

    React Native -IOS 开发环境搭建 web架构(基础) 安装依赖 * 必须安装的依赖有:Node.Watchman 和 React Native 命令行工具以及 Xcode. npm 镜 ...

  7. 在 React Native 中使用 Redux 架构

    前言 Redux 架构是 Flux 架构的一个变形,相对于 Flux,Redux 的复杂性相对较低,而且最为巧妙的是 React 应用可以看成由一个根组件连接着许多大大小小的组件的应用,Redux 也 ...

  8. React Native框架如何白盒测试-HIPPY接口测试架构篇

    本文转载自腾讯TMQ团队 ,侵权删. 1.开天辟地 Hippy是什么呢?简单点,能用JavaScript来写Android和iOS应用的框架, 类似业界的React Native. 好吧,我们还是严谨 ...

  9. 基于React Native的跨三端应用架构实践

    作者|陈子涵 编辑|覃云 “一次编写, 到处运行”(Write once, run anywhere ) 是很多前端团队孜孜以求的目标.实现这个目标,不但能以最快的速度,将应用推广到各个渠道,而且还能 ...

随机推荐

  1. Windows 切换 working directory

    用函数 _chdir() 例如用计划任务启动,pwd 是 system32 使用相对路径的地方会出错. 在 main 函数刚启动的时候转换一下 working directory 可解.

  2. windows下怎么同时使用python2和3

    windows命令行下,怎么能够自由的切换python2和3呢?当然不是切换目录!很多帖子告诉你,将python2目录下的python.exe文件改成python2.exe,pyhton3目录下的py ...

  3. 动画图解Git命令

    ​Git是一个开源的分布式版本控制系统,可以有效.高速的处理从很小到非常大的项目版本管理,是目前使用范围最广的版本管理工具 尽管Git是一个非常强大的工具,但我认为大多数人都会同意我的说法,即它也可以 ...

  4. 异常:NoSuchFieldError: BEST_MATCHING_HANDLER_ATTRIBUTE

    出现的原因 pom 依赖之间不匹配导致 当前的 pom 调整后访问资源成功后面的 pom

  5. App《最美诗词》开发 -- Java后端(整合框架)

    本人一直是致力于Android开发,由于我们三位Android开发者 @老蔡 @不肯过江东 打算一起开发Android App<最美诗词>,需要服务器端的接口支持,所以便兼职做起了后端的代 ...

  6. C++如何求程序运行时间

    C++中常用clock()函数求运行时间,返回值类型为clock_t,返回值是程序运行到本次调用clock()函数经过的clock数,头文件为<time.h>. 用法: 1.求开始时间s= ...

  7. Windows 10配置VS Code C++环境(超详细,面向小白以及大佬们)

    看完这个,还有下一篇:门在这 我看了网上的大佬们配的我是在是看不懂啊?我是一个小白啊?这太难了,这阻挡不了我,想使用这很骚的IDE,于是在不断的摸索下,终于配置成功,小白们也不用慌,这次非常简单.一定 ...

  8. RF(元素定位)

    1.id 定位 Open Browser https://www.baidu.com gc Input Text id=kw selenium #注意 id 的值 kw 没有用引号括起来 Close ...

  9. 一个epoll的简单例子

    epoll事件机制的触发方式有两种:LT(电平触发)和ET(边沿触发) EPOLLIN事件: 内核中的socket接收缓冲区 为空(低电平) 内核中的socket接受缓冲区 不为空(高电平) EPOL ...

  10. 1) drf 整体了解

    一.接口 """ 1.什么是接口:url+请求参数+响应数据 | 接口文档 ​ 2.接口规范: url:https,api,资源(名词复数),v1,get|post表示操 ...