本页逐一拆解 React Native 新架构的四个核心组件——JSI、Fabric、TurboModules、Bridgeless——说明每个组件解决了旧架构的哪个具体问题,以及它们共同构成的新通信模型与旧架构的对比。
新架构的四个核心组件
新架构不是一次简单的”优化”,而是对旧架构通信模型的根本性重写。四个组件各司其职,但都指向同一个目标:让 JS 和原生代码共享内存,消除 JSON 序列化开销。
JSI (JavaScript Interface)
是什么: JSI 是一层 C++ 抽象,让 JavaScript 引擎(Hermes 或 V8)可以直接持有 C++ 对象的引用,并同步调用其方法。
Host Object 机制: 原生侧暴露一个实现了 jsi::HostObject 接口的 C++ 对象,JS 侧拿到的是这个对象的 JS 包装(Proxy-like)。调用方法时直接进入 C++ 函数,没有序列化,没有队列,没有跨线程 IPC。
// 原生侧注册一个 Host Object (简化示意)
class MMKVHostObject : public jsi::HostObject {
jsi::Value get(jsi::Runtime& rt, const jsi::PropNameID& name) override {
// 直接返回 C++ 计算结果,JS 侧同步收到
if (name.utf8(rt) == "getString") {
return jsi::Function::createFromHostFunction(...);
}
}
};
对比旧架构: 旧架构的 NativeModules.XXX.method() 调用先序列化参数,投入消息队列,跨线程投递,等回调。JSI 调用是同步的函数调用——这就是 react-native-mmkv 能做到同步读写的原因,而 AsyncStorage 做不到。
Fabric (新渲染器)
是什么: Fabric 是旧渲染器的完全重写版本。旧渲染器的 C++ Shadow Tree 通过 Bridge 与 JS 通信;Fabric 的 Shadow Tree 通过 JSI 暴露给 JS,可以同步读写。
核心改进:
-
C++ Shadow Tree 共享: JS 侧可以通过 JSI 同步测量原生视图的尺寸,不再需要异步回调。
measure()在 Fabric 下是同步的。 -
Concurrent Rendering 支持: Fabric 的渲染管线可以被 React 的 Scheduler 中断。旧渲染器的提交是原子的,一旦开始必须跑完——这是为什么旧架构 JS 阻塞会直接导致 UI 掉帧。Fabric 允许高优先级更新(如用户触摸响应)打断低优先级渲染(如数据加载后的列表刷新)。
-
渲染管线统一: 旧架构的 Shadow Thread 和 UI Thread 是两条独立线程靠消息协调;Fabric 把布局计算(Yoga)和提交整合进同一个 C++ 渲染管线,减少了线程切换。
TurboModules
是什么: TurboModules 是新架构对”原生模块”系统的重写。旧的 NativeModules 在 App 启动时把所有模块全部初始化,不管用不用。TurboModules 是懒加载的——模块只在第一次被 JS 访问时才初始化。
Codegen 的角色: TurboModules 要求每个原生模块在 JS 侧提供 TypeScript 或 Flow 类型声明(.ts 文件)。构建时 Codegen 工具读取这些声明,自动生成 C++ 接口胶水代码,确保 JS 类型和原生类型一一对应,在编译期而非运行期发现类型不匹配。
// TurboModule 的 TS 类型声明 (NativeHaptics.ts)
import type { TurboModule } from 'react-native';
import { TurboModuleRegistry } from 'react-native';
export interface Spec extends TurboModule {
impact(style: string): void;
}
// Codegen 读取这个文件,生成对应的 C++ 头文件
export default TurboModuleRegistry.getEnforcing<Spec>('Haptics');
对比旧 Native Modules: 旧 Native Modules 在 RCTBridgeModule 注册,JS 侧通过 NativeModules.Haptics 访问——是弱类型的字典查找,JS 和原生类型靠开发者手动保持一致,出错在运行时才发现。
Bridgeless 模式
是什么: Bridgeless 不是新增功能,而是移除代码——完全不加载 Bridge 相关的初始化代码(RCTBridge、RCTCxxBridge)。所有通信走 JSI。
为什么需要单独说: 即使开启了 Fabric + TurboModules,旧架构的 Bridge 代码仍然可以存在作为 fallback(兼容还没迁移的第三方库)。Bridgeless 模式是明确声明”我不要 fallback,彻底删掉 Bridge”,这样启动时少加载一批代码,内存占用更低。
Expo SDK 54 的状态: SDK 54(RN 0.81)默认开启 Bridgeless。可以通过 app.json 中 newArchEnabled: true 声明,运行时通过 global.RN$Bridgeless === true 验证(见配套 Wiki 页面)。
旧架构 vs 新架构对比
| 维度 | 旧架构 | 新架构 |
|---|---|---|
| JS ↔ 原生通信 | JSON 序列化 + 异步消息队列 | JSI 直接 C++ 调用,同步 |
| 原生模块加载 | 启动时全量初始化 | TurboModules 懒加载 |
| 布局测量 | 异步,需回调 | Fabric 支持同步 measure() |
| 渲染可中断性 | 不可中断 | Fabric + Concurrent Rendering |
| 类型安全 | 运行时发现类型不匹配 | Codegen 编译期生成接口 |
| Bridge 代码 | 常驻内存 | Bridgeless 模式下完全不加载 |
| 第三方库兼容 | 所有库都支持 | 需要库明确支持新架构 |
最后一行是真实的 trade-off:新架构不向下兼容旧的 Native Modules 写法。生态迁移在 2024-2025 年基本完成,主流库已支持,但偶尔仍会遇到还在旧架构的库。
参见
- RN 旧架构 Bridge 详解
- RN 新架构验证方法
参考
版本说明
- 本页基于 2026-04-13 调研结果整理,适用范围以当前工具版本为准。