Turbo Module 是 React Native 原生模块的演进,构建于 JavaScript Interface (JSI) 之上。与 Bridge 不同,Turbo Module 同步工作且无需 JSON 序列化,从而显著提升性能。根据 Meta Engineering Blog, 2024,Turbo Module 是新架构的关键组件,在 React Native 0.76+ 中可用。
要点
Turbo Module 是 React Native 新架构的组件,取代了用于 JavaScript 与原生代码交互的经典 Bridge。与 Bridge 不同,在 Bridge 中每条消息都会被序列化为 JSON 并异步发送,Turbo Module 使用 JSI —— 一个允许 JavaScript 直接调用用 C++ 编写的函数的中间层。
Turbo Module 架构由 Meta 团队在 React Conf 2021 上作为代号为 “The New Architecture” 的更广泛 React Native 重构的一部分发布。除了 Turbo Module,新架构还包括 Fabric(新渲染器)、Codegen(代码生成器)和 JSI(通信接口)。这些组件共同解决了自 2015 年以来在 React Native 中积累的性能问题。
Turbo Module 解决了经典原生模块的三个关键问题:异步性(所有调用都通过队列)、序列化(每次调用都需要 JSON 转换)和加载(所有模块在应用启动时初始化)。使用 Turbo Module,原生方法被同步调用,数据无需复制即可传输,模块按需加载。
JSI(JavaScript Interface)是一个 C++ API,它在 JavaScript 引擎(Hermes 或 JSC)和原生代码之间创建一个中间层。JSI 提供宿主对象 —— 看起来像普通 JavaScript 对象和方法的 C++ 对象。当 JavaScript 调用此类对象的方法时,JSI 直接执行相应的 C++ 代码,无需序列化和线程切换。
JSI 与 Bridge 的关键区别在于没有数据复制。在 Bridge 中,每个值被序列化为 JSON、通过队列发送然后反序列化。JSI 传递内存中数据的指针,允许处理大量数据而不会损失性能。根据 Meta 的测试,JSI 调用比通过 Bridge 进行的类似调用快 5–10 倍。
JSI 定义了 HostObject 接口 —— React Native 在 JS 环境中注册为普通对象的 C++ 类。当 JS 代码访问 HostObject 的属性或调用其方法时,JSI 拦截该调用并执行 C++ 代码。这使得操作可以同步执行,无需等待 Bridge 队列。
// JSI HostObject 示例 —— 同步原生调用
class ImageCompressorHostObject : public jsi::HostObject {
jsi::Value get(
jsi::Runtime& rt,
const jsi::PropNameID& propName
) override {
auto name = propName.utf8(rt);
if (name == "compressImage") {
return jsi::Function::createFromHostFunction(
rt,
jsi::PropNameID::forUtf8(rt, name),
2,
[](jsi::Runtime& rt,
const jsi::Value& thisValue,
const jsi::Value* args,
size_t count) -> jsi::Value {
return jsi::Value(rt, compressNative(
args[0].asString(rt).utf8(rt),
args[1].asNumber()
));
}
);
}
return jsi::Value::undefined();
}
};
以上代码展示了 JSI HostObject 如何处理来自 JavaScript 的 compressImage 调用。该函数接收两个参数(路径字符串和品质数值),调用原生函数 compressNative 并返回结果 —— 全部同步完成,无需 Bridge,无需 JSON。这是 JSI 相较于经典架构的关键优势。
JSI 是 React Native 主运行时的一部分,不依赖于特定的 JavaScript 引擎。它既能与 Hermes 也能与 JavaScriptCore (JSC) 配合使用,为与原生环境通信提供统一接口。
Turbo Module 与 Bridge 的对比展示了 React Native 架构的演进。Bridge 是为 2015 年 React Native 的快速启动而设计的,但随着应用程序复杂性的增加,其局限性变得至关重要。Turbo Module 在架构层面解决了这些问题。
| 特性 | Bridge | Turbo Module |
|---|---|---|
| 调用速度 | 5–15 毫秒开销 | 0.1–0.5 毫秒开销 |
| 同步性 | 仅异步 | 同步和异步 |
| 序列化 | 每次调用的 JSON | JSI 对象无需复制 |
| 类型安全 | 否 | Codegen + TypeScript |
| 初始化 | 启动时加载所有模块 | 按需懒加载 |
在实践中,差异在频繁调用原生方法时最为明显 —— 例如在处理媒体或使用 GPU 时。对于不频繁的调用(每会话一次),性能差异可以忽略不计。Turbo Module 还简化了大型二进制数据 —— 图像、视频、二进制协议 —— 的处理,而在 Bridge 中这些需要文件系统的解决方案。
创建 Turbo Module 始于在 TypeScript 中定义规范。Codegen 基于此规范自动生成 C++ 接口和 Objective-C/Java 存根。这完全改变了开发方法 —— 开发者只需描述一次 API,Codegen 就会创建其余部分。
// ImageCompressor.ts —— Turbo Module 规范
import type { TurboModule } from 'react-native';
import type { Double } from 'react-native/Libraries/Types/CodegenTypes';
export interface Spec extends TurboModule {
compressImage(
imagePath: string,
quality: Double
): Promise<string>;
}
Codegen 分析 TypeScript 规范并生成 C++ HostObject、Objective-C 协议和 Java 接口。开发者只需实现原生逻辑。这种方法保证了 JavaScript 端和原生端的类型始终一致,消除了手动映射的错误。
// 适用于 iOS 的 TurboModule 实现(生成的存根)
@interface ImageCompressorModule ()
RCT_EXPORT_MODULE(ImageCompressor)
@end
@implementation ImageCompressorModule
RCT_EXPORT_METHOD(compressImage:(NSString *)imagePath
quality:(NSNumber *)quality
resolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)
{
NSData *compressed = [ImageProcessor compressAtPath:imagePath
quality:quality.doubleValue];
resolve([NSString stringWithUTF8String:compressed.UTF8String]);
}
@end
一个重要优势是懒加载。Turbo Module 不在应用启动时初始化,而是在首次从 JavaScript 访问时创建。与所有原生模块立即加载的经典方法相比,这可将应用启动时间缩短 30–50%。
从 Bridge 迁移到 Turbo Module 不需要完全重写应用程序。React Native 0.73+ 并行支持两种架构 —— Bridge 模块继续工作,而新模块可以作为 Turbo Module 创建。这允许逐步迁移,一个模块一个模块地进行。
要在 React Native 0.76+ 项目中启用新架构,将 react-native.config.js 文件中的 newArchEnabled 标志设置为 true。之后,所有现有的原生模块继续通过 Bridge 工作,而新模块可以作为 Turbo Module 创建。Codegen 自动处理这两种变体。
// react-native.config.js —— 启用新架构
module.exports = {
project: {
ios: {},
android: {},
},
assets: [],
newArchEnabled: true,
};
建议从最常从 JavaScript 调用的模块开始迁移 —— 它们将获得最大的性能提升。不常调用的模块(每会话一次)可以保留在 Bridge 上而不会显著损失性能。
常见问题解答
不能,Turbo Module 需要 React Native 0.73+ 并启用新架构。从 0.76 版本开始,新架构变得稳定,推荐用于生产项目。
是的,Turbo Module 支持两个平台。JSI 是一个跨平台的 C++ 层,Codegen 分别为 iOS 和 Android 生成 Objective-C 和 Java 存根。
不必,Turbo Module 通过 JSI 与任何 JS 引擎配合使用。但推荐使用 Hermes,因为它针对 JSI 和新的 React Native 架构进行了优化。
Turbo Module 的调试通过 Xcode 或 Android Studio 进行,就像普通原生代码一样。此外,还可以使用 Flipper 跟踪 JSI 调用和模块性能。
Turbo Module 实际上不影响应用程序大小。JSI 的 C++ 代码已经是 React Native 的一部分,生成的代码是最小的 —— 只有接口,没有逻辑重复。
总结
我们将开发一款交钥匙移动应用程序
IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。