【碎片八股文 #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 是怎么实现跨进程通信的?