React Native 架构升级¶
关于架构升级¶
新架构¶
- React Native 0.68 includes preview of the New Architecture opt-in.
旧架构¶
架构设计¶
流程简述¶
- React 编译 → JS 代码 -(JSC引擎)-> Bridge
-
Bridge 分三部分
- Shadow Tree:定义UI效果、处理交互
- Native Modules:原生模块,如蓝牙、摄像头、定位、网络等
- 异步 JSON:公共交互语言,JS 和 Native 都识别。
-
转换成 JSON → 传递给 Native
线程模型¶
-
JS 线程
- JS 代码执行线程,将 React 源码通过 Metro 打包后生成 js bundle,传递给 JS 引擎进行解析
-
Main 线程(UI 线程 或 原生线程)
- 负责原生渲染(Native UI)与调用原生模块(Native Modules)
-
Shadow 线程(Layout 线程)
- 创建 Shadow Tree 来模拟 React 结构树(类似 vDOM)
- 再由 Yoga 引擎将 Flexbox 等样式,解析成原生平台的布局方式
渲染机制¶
- Android、IOS 原生的布局,不支持 Flexbox
-
流程如下
- 1、Javascript:JS Thread → 结构、属性、样式 → 2
- 2、Shadow Tree:Shadow Thread → 宽高、位置 → 3
- 3、Native View:Main Thread → 渲染完成
-
流程图
线程交互¶
- 从线程视角理解架构
- 交互图
-
Bridge 的三个特点
- Async:异步、不需要等待;
- Serialized:进入 Bridge 的数据要序列化,出来的数据要反序列化;
- Batched:多个 JSON 消息绑定在一起,一起发送,提高 Bridge 沟通性能。
启动过程¶
- 流程图
-
Yoga 引擎
- facebook 推出,用来将 React 样式解析成原生样式。
应用过程¶
- 流程图
新架构¶
旧架构的问题¶
- 问题一:高并发场景下,消息积压在 Bridge 两侧,导致严重的性能问题。
- 解法一:重构 Bridge,解决性能瓶颈。
新旧架构对比¶
- 对比图
- 特性一、在 React 部分增加静态类型检查(TypeScript),通过
CodeGen
来实现。 - 特性二、 引入 JSI,作为 JS 与 JS 引擎之间的一个抽象层。
- 特性三、Bridge 改造成了 Fabric 和 Turbo Modules。
- 特性四、Native 层做了简化。
三大改动¶
-
JS 层
- 支持 React 16+ 新特性
- 增强 JS 静态类型检查(CodeGen)
- 引入JSI,允许替换不同的 JavaScript 引擎
-
Bridge 层
- 划分成 Fabric 和 Turbo Modules 两部分,分别负责 UI 管理和 Native 模块管理。
-
Native 层
- 精简核心模块,将非核心部分拆分出去,将作为社区模块,独立更新维护
CodeGen:增强类型安全¶
- CodeGen 是 facebook 推出的代码生成工具
- 通过 CodeGen,自动将 flow 或 typescript 等有静态类型的 JS 代码翻译成 Fabric 和 Turbo Modules 使用的接口文件。
-
加入类型约束后的作用
- 减少来数据类型错误(比如 IOS 遇到类型错误会静默失败,android 遇到类型错误会崩溃)
- 减少了数据验证的次数,提升通信性能(之前每次通信前都会验证数据类型)
引入 JSI (Javascript Interface)¶
- JSI 可以让 JS 运行在不同的 JS 解析引擎上
- 默认的 JS Core、移动端的 Hermes、微软的 Chakra、谷歌的 V8 等
- JSI 是一个 C++写的轻量级框架, 让 JS 对象可以直接获得对 C++对象的引用 ,从而允许 JS 直接调用 Native。
- 完美解决了上一代架构 Bridge 通信压力的问题:不需要额外的跨线程的消息通信,不必对 JSON 序列化和反序列化
重构 Bridge 之 Fabric¶
- Fabric 是整个架构中的新 UI 层
- 简化了之前的渲染流程
- 优先级较高的任务可以直接与 native 层交互,减少不必要的线程操作,提升 UI 渲染性能。
- 旧渲染流程
- 新渲染流程
重构 Bridge 之 TurboModules¶
- 通过 JSI,可以让 JS 直接调用 Native 模块,实现 同步 操作。
-
实现 Native 模块按需加载,减少启动时间,提高性能
- 旧架构 Native Modules 不管是否用到,启动时都会初始化,因为 Native 不知道 JS 将会调用哪些功能模块;
- 新架构只初始化将来需要的模块。
精简核心模块(Lean Core)¶
- 将 React-native 核心模块瘦身
- 非必要的包,移到社区模块,单独维护:如 AsyncStorage、WebView 等
启动过程¶
- 启动流程图