RN的JSI 原理
React Native 的 JSI(JavaScript Interface) 是新架构(New Architecture)的核心,它解决的是 JavaScript 和 Native 之间如何高效通信的问题。简单理解:
JSI 是一个 C++ 层的接口,让 JS 可以直接调用 C++ 对象,不再通过旧 Bridge 的 JSON 序列化通信。 (React Native)
下面从原理深入拆解。
1. 旧 RN Bridge 的问题
以前 RN 架构:
JavaScript
|
|
Bridge
|
|
Native (Java/Kotlin/ObjC/Swift)
例如:
JS:
NativeModule.getUser(100)
实际流程:
JS
|
| 1. 创建消息
|
| 2. JSON序列化
|
Bridge Queue
|
| 3. 异步传递
|
Native
|
| 4. 执行
|
| 5. JSON返回
|
JS
问题:
① 序列化成本
比如:
{
imageBuffer: ArrayBuffer(30MB)
}
Bridge 需要:
JS Object
|
JSON.stringify
|
字符串
|
JSON.parse
|
Native Object
大量数据复制。
② 异步限制
Bridge 天生异步:
const result = native.getValue();
console.log(result);
不能直接返回:
必须:
native.getValue(result=>{
console.log(result)
})
③ 无法传递复杂对象
只能传:
string
number
boolean
array
object
不能直接传:
Native Object
Camera Frame
Database Cursor
Audio Buffer
2. JSI 的核心思想
JSI 引入一个 C++ 中间层:
JavaScript Engine
Hermes / JSC / V8
|
|
JSI
(C++ Interface)
|
|
Native C++ Object
JS 不再调用 Java/ObjC。
而是:
JS
|
|
C++ Object
|
|
Native API
React Native 官方描述中,JSI 允许 JavaScript 持有 C++ 对象引用,并直接调用方法,避免序列化开销。 (React Native)
3. JSI 最核心的三个概念
① Runtime
JSI 最重要的对象:
jsi::Runtime
它代表:
当前运行 JavaScript 的环境
例如:
Hermes:
Hermes VM
|
|
jsi::Runtime
你的 C++ 可以通过 Runtime 操作 JS:
runtime.global()
获取:
global
对象。
② Host Function
让 C++ 暴露一个 JS 函数。
例如 C++:
auto hello = jsi::Function::createFromHostFunction(
runtime,
jsi::PropNameID::forAscii(runtime,"hello"),
0,
[](Runtime& rt,
const Value& thisValue,
const Value* args,
size_t count){
return String::createFromUtf8(
rt,
"Hello JSI"
);
}
);
注册:
runtime.global()
.setProperty(
runtime,
"hello",
hello
);
JS:
console.log(
hello()
)
输出:
Hello JSI
调用链:
JS hello()
|
|
Hermes Runtime
|
|
C++ Lambda
|
|
return Value
没有 Bridge。
③ Host Object
这是 JSI 最强的地方。
以前:
JS Object
{
name:"camera"
}
是真 JS 内存对象。
JSI:
JS Object
|
|
HostObject Proxy
|
|
C++ Object
JS 保存的是:
C++对象引用
例如:
C++:
class Camera : public jsi::HostObject {
public:
Value get(
Runtime& rt,
const PropNameID& name
){
if(name=="takePhoto"){
return Function(...)
}
}
};
JS:
camera.takePhoto()
实际上:
camera
|
|
C++ Camera Instance
|
|
Native Camera API
4. JSI 调用流程
例如:
storage.set("name","Tom")
使用 JSI 的库:
JS
|
|
storage.set()
|
|
JSI Runtime
|
|
C++ HostFunction
|
|
C++ Storage Engine
|
|
MMKV / SQLite / File
整个过程:
没有:
JSON.stringify
JSON.parse
Message Queue
Async callback
5. JSI 和 TurboModule 的关系
很多人容易混淆:
React Native New Architecture
JavaScript
|
|
JSI
/ \
TurboModules Fabric
Native Modules UI Rendering
关系:
JSI
底层通信机制:
JS 怎么调用 C++
TurboModules
模块系统:
Native module 怎么注册和加载
例如:
NativeModules.Camera.takePhoto()
TurboModule 最终通过 JSI 调用 Native。 (Mintlify)
Fabric
UI 渲染系统:
<View>
<Text>
这些组件通过新的渲染流程和 JSI 通信。
6. 为什么 JSI 性能高?
对比:
Bridge
JS
|
对象复制
|
JSON序列化
|
线程队列
|
JSON解析
|
Native
成本:
O(n)
复制数据
JSI
JS
|
指针引用
|
C++
对象
成本:
O(1)
直接调用
尤其适合:
-
Camera
-
Video
-
Audio
-
Animation
-
Database
-
Large ArrayBuffer
例如 VisionCamera 利用 JSI 处理实时视频帧,就是因为 JSI 可以绕开 Bridge 的序列化瓶颈。 (React Native)
7. JSI 内存模型
重点:
JS GC 管 JS 对象:
Hermes GC
JS Object
C++ 管 Native:
C++ Heap
HostObject
两者通过:
std::shared_ptr
关联。
例如:
JS variable
const db = new Database()
|
|
v
C++ Database Object
shared_ptr<Database>
当 JS 不再引用:
GC
|
释放 HostObject
|
shared_ptr--
|
delete C++
8. JSI 为什么需要 C++?
因为:
Android:
Java/Kotlin
iOS:
ObjC/Swift
不统一。
C++:
C++
/ \
Android iOS
成为跨平台层。
所以 RN 新架构大量核心代码迁移到 C++。 (React Native)
9. 一个简单心智模型
把旧 Bridge 想象成:
两家公司通信,需要写邮件,翻译,再发送。
JS公司
写邮件(JSON)
↓
Bridge
↓
Native公司
JSI:
两家公司共享电话。
JS
|
直接打电话
|
Native
总结一句话
JSI = React Native 中连接 JS Runtime 和 C++ Native 世界的一层 C++ 接口。它通过让 JS 持有 C++ 对象引用,实现同步调用、零 JSON 序列化、高性能 Native 交互,是 TurboModules 和 Fabric 的底层基础。 (React Native)
如果继续深入,可以研究 JSI 源码结构(jsi.h)、Hermes Runtime、HostObject 生命周期、如何手写一个 JSI Module。
更多推荐


所有评论(0)