【碎片八股文 #001】为什么 React Native 要用 Bridge 通信?
一、面试题原文
面试官: 你知道 React Native 的 JS 代码是怎么调用到原生模块的吗?
候选人: 通过 Bridge 吧......但不太清楚原理。
面试官心里想: 能说出数据序列化、异步通信、性能瓶颈就很不错了。
二、常见误答
很多人只记住了"Bridge 是桥梁"这个比喻,但说不清楚:
- Bridge 具体做了什么?
- 为什么要用 JSON 序列化?
- 为什么说 Bridge 有性能问题?
这些都是面试官会追问的点。
三、正确理解
React Native 的 Bridge 是连接 JavaScript 线程和 Native 线程的异步通信机制。
核心流程
- JS 层调用原生模块
比如 JS 代码调用NativeModules.CameraModule.takePicture()
- 参数序列化为 JSON
Bridge 把 JS 的参数对象转成 JSON 字符串 - 通过消息队列传递
JSON 字符串被放入 Bridge 的消息队列,等待 Native 线程处理 - Native 层反序列化并执行
Native 线程从队列中取出消息,解析 JSON,找到对应的原生模块方法并执行 - 结果返回 JS
Native 执行完后,结果同样通过 JSON 序列化 → Bridge 队列 → JS 反序列化
为什么要这样设计?
因为 JavaScript 和 Native 代码运行在不同的线程,无法直接互相调用。
- JavaScript 跑在 JS 线程(通常是 JavaScriptCore 或 Hermes 引擎)
- 原生代码跑在 Native 线程(Android 的 Java/Kotlin,iOS 的 Objective-C/Swift)
Bridge 就是这两个世界之间的"翻译官"。
四、图解理解
arduino
┌─────────────┐ ┌──────────────┐
│ JS Thread │ │ Native Thread│
│ │ │ │
│ 调用方法 │ │ 原生模块 │
└──────┬──────┘ └──────▲───────┘
│ │
│ 1. 序列化参数为 JSON │
▼ │
┌─────────────────────────────────────┐ │
│ Bridge 消息队列 │ │
│ [{ module: "Camera", │ │
│ method: "takePicture", │ │
│ args: [...] }] │ │
└─────────────────────────────────────┘ │
│ │
│ 2. 异步传递 │ 4. 返回结果
▼ │
│ 3. 反序列化并执行 │
└────────────────────────────────┘
五、Bridge 的性能问题
问题 1: JSON 序列化/反序列化开销
每次跨语言调用都要做两次序列化:
- JS → JSON → Native
- Native → JSON → JS
数据量大或调用频繁时,这个开销就很明显。
问题 2: 异步通信延迟
Bridge 是异步的,消息要排队处理。高频调用(比如动画、滚动)时会有卡顿感。
问题 3: 无法直接传递复杂对象
JSON 只能表示基础类型,像 ArrayBuffer
、Function
这些无法直接传递,必须转换或拆分。
六、延伸提问
1. 为什么 React Native 要推出新架构 Fabric?
因为 Bridge 的性能瓶颈在 UI 渲染场景下尤其明显。Fabric 通过 JSI(JavaScript Interface) 直接让 JS 调用 Native,跳过了序列化和消息队列。
2. JSI 是如何解决 Bridge 问题的?
JSI 让 JavaScript 可以直接持有 Native 对象的引用,调用时不需要序列化:
scss
// 旧架构:通过 Bridge
NativeModules.CameraModule.takePicture()
// 新架构:通过 JSI
global.camera.takePicture() // 直接调用 Native 对象
性能提升可达 2-10 倍。
3. 为什么不一开始就用 JSI?
因为 JSI 需要为每个原生模块写 C++ 绑定,开发成本高。Bridge 虽然慢,但对开发者友好,早期快速迭代时是合理选择。
七、记忆口诀
"Bridge 异步传,性能略吃亏;JSI 直接连,性能翻几倍。"
八、碎片笔记
核心关键词: Bridge、JSON 序列化、异步通信、JSI、Fabric
重点记忆:
- Bridge 是消息队列 + JSON 序列化的异步通信机制
- 性能瓶颈在于序列化开销和异步延迟
- 新架构用 JSI 替代 Bridge,实现同步直接调用
实际应用:
- 如果你的 RN 项目有高频 Native 调用(比如自定义手势、音视频处理),升级到新架构能显著提升性能
- 老项目的 Native Module 如果要迁移到 JSI,需要用 C++ 重写绑定层
今天的碎片,帮你面试少挂一次。
下一篇预告: 【碎片八股文 #002】Binder 是怎么实现跨进程通信的?