如果你说的是 React Native New Architecture 里的 TurboModule,可以把它理解成:
TurboModule = React Native 用 JSI 把 JS 与原生模块连接起来的一套新机制。
它主要解决旧架构中 Bridge JSON 序列化 + 异步消息队列 带来的性能和类型安全问题。
1. 先看旧架构 Bridge
传统 RN:
javascript
JavaScript
│
│ JSON / Message
▼
Bridge
│
│ JSON / Message
▼
Native Module
│
Android / iOS
例如:
scss
NativeModules.UserModule.getUser(123)
实际上经历了类似:
arduino
JS 调用
↓
参数序列化
↓
Bridge 消息队列
↓
Native 接收
↓
反序列化
↓
Java/Kotlin/Obj-C/Swift
↓
结果序列化
↓
Bridge
↓
JS
所以 Bridge 本质上是一个跨语言消息通信层。
2. TurboModule 的核心变化
TurboModule 配合 JSI(JavaScript Interface) :
javascript
JavaScript
│
│ JSI
▼
┌───────────────┐
│ TurboModule │
│ Binding │
└───────┬───────┘
│
C++ / JNI / Obj-C++
│
┌───────┴───────┐
▼ ▼
Android iOS
Kotlin/Java Obj-C/Swift
关键区别:
以前:
arduino
JS → JSON → Bridge → Native
现在:
JS → JSI → Native
JSI 允许 JavaScript 引擎直接与 C++/Native 对象交互。
3. TurboModule 最核心的三个东西
可以记成:
Spec
↓
Codegen
↓
TurboModule
↓
JSI
↓
Native
① Spec:定义接口
例如:
typescript
export interface Spec extends TurboModule {
getUser(id: number): Promise<User>;
}
你告诉 RN:
我有一个 Native Module,它有
getUser()方法。
② Codegen:自动生成类型和绑定代码
New Architecture 非常重要的一点是:
JS 与 Native 之间的接口不是手写一套套胶水代码,而是通过 Codegen 生成。
例如:
csharp
TypeScript Spec
↓
Codegen
↓
┌───────────────┐
│ JS interface │
│ C++ binding │
│ Native types │
└───────────────┘
这样可以减少:
- 参数类型不一致
- 手写 Bridge
- 大量 boilerplate
- JS / Native 接口漂移
4. 真正调用的时候发生什么?
假设:
ini
const user = await UserModule.getUser(123);
大致过程:
scss
JS
│
│ UserModule.getUser(123)
▼
JSI
│
▼
TurboModule Binding
│
▼
C++ / JNI / Obj-C++
│
▼
Native Module
│
▼
getUser(123)
返回:
javascript
Native
│
▼
Native result
│
▼
JSI
│
▼
JavaScript Promise
这里最重要的是:
TurboModule 并不是"JavaScript 直接调用 Java/Kotlin/Swift"。
中间仍然存在 Native Binding / JSI / C++ 等机制。
5. 为什么 JSI 很重要?
JSI 可以让 JS 持有一个 Native/C++ 对象的引用。
传统 Bridge 更像:
css
JS:
{
type: "CALL_MODULE",
module: "Camera",
method: "takePhoto",
args: [...]
}
然后把这个消息扔给 Native。
而 JSI 更接近:
css
JS Object
│
└──→ Native/C++ HostObject
JavaScript 调用:
scss
camera.takePhoto()
最终可以进入 Native/C++ 实现。
所以它减少了传统 Bridge 中大量的:
对象
↓
序列化
↓
传输
↓
反序列化
6. TurboModule 为什么叫 Turbo?
一个很重要的特性:
Lazy Loading
传统 Native Module 很多情况下会在启动阶段初始化:
RN 启动
↓
初始化大量 Native Modules
↓
JS 开始执行
TurboModule 可以做到:
sql
RN 启动
↓
只注册 Module
↓
JS 真正使用 UserModule
↓
才创建 UserModule
也就是:
Register
↓
Lazy
↓
Instantiate
因此可以减少启动阶段不必要的初始化。
7. TurboModule 和 Fabric 是什么关系?
这是 RN New Architecture 非常容易混淆的一点。
sql
React Native New Architecture
│
┌───────────┴───────────┐
▼ ▼
TurboModule Fabric
│ │
Native Modules Native UI Components
│ │
相机/定位/存储/etc View/Text/Image
简单记:
| 技术 | 解决什么 |
|---|---|
| JSI | JS ↔ Native 的底层通信能力 |
| TurboModule | Native Module |
| Fabric | Native UI / 渲染 |
| Codegen | JS ↔ Native 类型/接口生成 |
| Hermes | JavaScript Engine |
所以:
TurboModule ≠ JSI
JSI 是底层能力,TurboModule 是建立在 JSI/Codegen 等机制上的 Native Module 架构。
8. 和旧 NativeModule 对比
javascript
旧架构
JS
│
▼
Bridge
│
├── JSON Serialize
├── Message Queue
└── JSON Deserialize
│
▼
NativeModule
TurboModule:
新架构
JS
│
▼
JSI
│
▼
TurboModule Binding
│
▼
Native
核心收益:
① 减少 Bridge 通信开销
② 类型由 Codegen 保证
③ 支持 Lazy Loading
④ Native 对象可以通过 JSI 暴露
⑤ 更容易支持同步/高性能 Native 调用场景
9. 但是有一个非常重要的误区
不要简单理解成:
"TurboModule = 同步调用 Native,所以性能一定更高。"
并不是。
例如:
scss
getUser(): Promise<User>
依然可以是异步的。
真正的变化是:
通信机制
从:
arduino
Message + Serialization + Bridge
变成:
JSI + Native Binding
所以性能收益主要来自减少通信和序列化层的开销,而不是"所有 Native API 都变成同步"。
10. 面试时可以这样回答
如果面试官问:
TurboModule 原理是什么?
可以用这一套回答:
TurboModule 是 React Native New Architecture 中替代传统 NativeModule Bridge 的 Native Module 机制。它基于 JSI 和 Codegen,通过 TypeScript/Flow 定义 Native Module 的 Spec,再由 Codegen 生成 JS 与 Native 之间的类型和绑定代码。JS 调用 TurboModule 时,不再像旧架构一样通过 Bridge 将调用序列化成 JSON 消息,而是通过 JSI 进入 Native Binding,再调用具体的 Java/Kotlin 或 Objective-C/Swift 实现。同时 TurboModule 支持 Lazy Loading,可以在真正使用 Module 时再进行实例化,从而降低启动成本。
如果继续往底层追问:
javascript
JS
↓
Hermes
↓
JSI
↓
HostObject / HostFunction
↓
TurboModule Binding
↓
C++ / JNI / Obj-C++
↓
Java/Kotlin / Obj-C/Swift
这条链路基本就是 TurboModule 原理的核心。