旧架构的核心是 Bridge,新架构的核心是 JSI + Fabric + TurboModules。本质区别在于 JS 和 Native 怎么通信。
一、核心区别:JS 与 Native 的通信方式
旧架构:Bridge
JS 和 Native 不能直接对话,所有数据都得先序列化成 JSON,扔过 Bridge,对面再反序列化。就像两个人说话必须通过翻译,而且翻译还是异步的------你说完得等回复。
JS → 序列化为 JSON → Bridge → 反序列化 → Native
Native → 序列化为 JSON → Bridge → 反序列化 → JS
这带来几个问题:
- 每次通信都有序列化开销,数据量大的时候很明显
- 通信是异步的,JS 没办法同步拿到 Native 的返回值
- 动画场景最痛:每一帧都要过一遍 Bridge,Bridge 稍微忙一点就掉帧
新架构:JSI
JSI 是一个 C++ 层,让 JS 引擎可以直接拿到 C++ 对象的引用,就像直接调用本地方法一样,不用再走 JSON 序列化这条路了。
JS → 直接调用 C++ 对象方法 → Native(无序列化,可同步)
好处是:
- 没有序列化开销
- 可以同步调用,不一定非得 callback
- JS 和 Native 能共享对象引用
二、新架构三件套
| 组件 | 替代什么 | 作用 |
|---|---|---|
| JSI | Bridge | JS ↔ Native 直接通信,无序列化开销 |
| Fabric | UIManager(旧渲染器) | 新渲染系统,支持并发渲染,Shadow Tree 可跨线程安全访问 |
| TurboModules | NativeModules | 按需懒加载 Native 模块,启动更快 |
JSI
本质上是对 JS 引擎(Hermes / JSC)的一个 C++ 抽象层。Native 侧通过 JSI 暴露 HostObject 给 JS,JS 侧就像操作普通对象一样调用 Native 能力。
Reanimated 2、react-native-gesture-handler 这些库能跑在 UI 线程,根本原因就是它们基于 JSI 实现的。
Fabric
旧架构的 UIManager 只能在主线程跑,Fabric 把 Shadow Tree 设计成不可变的(immutable),任意线程都可以安全读取,这样渲染计算就不用非得在主线程做了。
另外 Fabric 支持 React 的并发特性,渲染任务可以被中断、有优先级,而不是之前那种一旦开始就必须跑完。
渲染流程:JS 描述 UI → C++ Shadow Tree 计算布局(Yoga)→ 挂载到真实 Native View
TurboModules
旧架构启动时会把所有 Native 模块都初始化一遍,不管你用没用到,白白浪费启动时间。TurboModules 改成了懒加载,第一次用到才初始化。同样基于 JSI,所以也支持同步调用。
三、架构对比
| 维度 | 旧架构(Bridge) | 新架构(JSI/Fabric) |
|---|---|---|
| JS ↔ Native 通信 | 异步,JSON 序列化 | 直接 C++ 调用,可同步 |
| 渲染器 | UIManager,只能主线程 | Fabric,Shadow Tree 不可变,多线程安全 |
| Native 模块加载 | 启动时全量初始化 | 按需懒加载 |
| 动画 | Animated 跑 JS 线程,JS 一忙就掉帧 | 动画逻辑可直接跑 UI 线程(Reanimated) |
| React 并发特性 | 不支持 | 支持(可中断渲染) |
| 启动速度 | 慢 | 快 |
四、版本节点
| 版本 | 发生了什么 |
|---|---|
| 0.63 及以前 | 纯旧架构 |
| 0.68 | JSI / Fabric / TurboModules 作为实验性功能,可手动开启 |
| 0.71 | 首次全面支持 Apple Silicon(苹果ARM 架构芯片) |
| 0.74 | Hermes 默认启用,新架构基本可用,推荐 M 系列 Mac 的版本 |
| 0.76 | 新架构默认开启,正式成为主线 |
五、对实际开发的影响
为什么 Reanimated / RNGH 要求新架构
因为它们基于 JSI,动画和手势逻辑直接在 UI 线程跑,完全绕开了 JS 线程。旧架构下只能用 Animated + PanResponder,性能上限低很多。
同步调用 Native 变成了可能
旧架构下拿 Native 返回值只能靠 callback 或 Promise。新架构支持同步调用,适合需要立刻拿到结果的场景,比如读设备信息、本地存储等。
启动速度
如果项目里 Native 模块比较多,TurboModules 的懒加载效果会比较明显。
迁移到新架构成本
用旧 Bridge 方式写的 Native Module 需要改造。0.74+ 的主流第三方库基本都适配了,自己写的模块要另说。