Skip to content
雲里
里雾

RN 旧架构 Bridge 详解

react native 开发 更新于 2026/4/13

本页详解 React Native 旧架构的 Bridge 通信机制,介绍三线程模型的构成,以及 JSON 消息队列在序列化开销、异步延迟和单通道阻塞三方面带来的具体性能瓶颈。

三线程模型

旧架构(RN 0.68 及之前的默认模型,RN 0.73 之前无法完全绕开)运行在三条线程上:

线程职责
JS Thread执行 JavaScript bundle,运行 React reconciler、业务逻辑、事件处理
UI Thread (Main Thread)执行真实的原生视图操作(UIKit / Android View),处理触摸事件
Shadow Thread (Yoga Thread)运行 Yoga 布局引擎,将 React 的 flexbox 描述计算成具体尺寸,结果再传给 UI Thread

三条线程不共享内存——这是旧架构最根本的设计约束,一切痛点都从这里派生。

JSON 消息队列的工作方式

JS Thread 与 UI Thread / Shadow Thread 之间唯一的通信通道是 Bridge:一条异步的序列化消息总线。

  1. JS 侧调用 NativeModules.SomeModule.someMethod(arg1, arg2) 时,参数被序列化成 JSON 字符串,放入发送队列。
  2. Bridge 在适当时机(批量刷新,通常跟随 JS run loop)将队列里的消息跨线程投递给原生侧。
  3. 原生侧反序列化 JSON,执行对应的原生方法,结果再序列化回 JSON 投递回来。
  4. JS 侧在回调或 Promise 中收到结果,再次反序列化。

整个过程没有共享指针,没有直接的函数调用——所有数据都要经历两次 JSON 序列化/反序列化

简化伪代码示例

// JS 侧——发出调用后立即返回,结果是异步的
NativeModules.Haptics.impact('medium', (result) => {
  // 这个回调要等到 Bridge 投递完成才触发
  // 在触摸事件发生到此回调之间,帧已经过去了
  console.log(result);
});

// 原生侧无法被 JS 同步读取——下面的代码在旧架构不存在
// const width = NativeModules.Layout.getViewWidth(ref); // 不可能同步

三个具体性能痛点

1. 序列化开销

每次 JS 和原生之间传递数据都要序列化成 JSON、传输、再反序列化。对于高频操作(手势、动画每帧回调),这意味着每帧都在做大量字符串解析。Reanimated 1 之所以要把动画逻辑整个搬到原生侧执行,根本原因就是跨 Bridge 每帧传数据太慢。

2. 异步延迟,无法同步读原生状态

JS 侧无法同步获取原生视图的尺寸、滚动位置、输入框内容等状态。必须发消息 → 等回调。这导致一类典型问题:用户快速滚动时,JS 侧拿到的 scrollY 总是”过去”的值,实现视差滚动、吸顶效果时往往有抖动。

3. 单通道阻塞

Bridge 是单一的批量刷新通道,JS Thread 和 UI Thread 都往同一个队列里塞消息。当 JS 做大量计算(如渲染长列表)时,UI Thread 的消息处理也会积压——JS 卡顿直接导致 UI 掉帧,二者无法真正并发。新架构的 Concurrent Rendering(配合 Fabric)正是要解决这个问题:让渲染可中断,UI Thread 不被 JS 阻塞。

版本备注

参见

参考

版本说明