React Native(RN)的经典架构可以理解为三层架构

┌──────────────────────────────┐
│        JS Layer              │
│ React + JavaScript           │
└──────────────┬───────────────┘
               │
      Bridge(桥接层)
               │
┌──────────────┴───────────────┐
│ Native Layer                 │
│ Android(Java/Kotlin)         │
│ iOS(Objective-C/Swift)       │
└──────────────────────────────┘

如果是新版 RN(Fabric + JSI),Bridge 已经逐渐被 JSI 替代,但面试中一般都会先讲经典 Bridge,再讲新架构。


一、JS层(JavaScript Layer)

JS 层就是 React 代码运行的地方。

负责:

  • React组件

  • 业务逻辑

  • 状态管理(Redux、Mobx)

  • 网络请求

  • 页面跳转

  • 调用 Native API

例如

function App() {
  return (
    <View>
      <Text>Hello RN</Text>
    </View>
  );
}

React 会先生成 Virtual DOM。

RN 并不会生成 HTML。

而是生成:

React Element

↓

Shadow Tree

↓

告诉 Native:

创建一个 Text

创建一个 View

设置宽高

设置背景颜色

所以:

JS 不负责真正画界面。


二、Bridge(桥接层)

Bridge 是 RN 最核心的一层。

它负责:

JS ←→ Native 通信。

因为:

JavaScript

不能直接调用

Java

或者

Objective-C。

所以需要一个翻译官。

例如:

JS:

Alert.alert("Hello");

不能直接执行。

Bridge 会变成:

Android

JS

↓

Bridge

↓

Java

↓

AlertDialog.show()

iOS

JS

↓

Bridge

↓

OC

↓

UIAlertController

Bridge 就像 RPC。


Bridge 的通信方式

RN 采用:

JSON Message Queue(消息队列)

JS 发消息:

[
  moduleId,
  methodId,
  params
]

例如:

[
  5,
  2,
  ["hello"]
]

表示:

Module:

AlertModule

Method:

show()

参数:

hello

Bridge 收到以后:

找到对应 Native Module

调用 Native 方法

执行。


三、Native 层(原生层)

Native 层真正负责:

Android:

TextView

Button

RecyclerView

Canvas

iOS:

UILabel

UIButton

UITableView

RN 并没有自己画 UI。

而是:

React

Bridge

真正创建

Android View

iOS View

所以 RN 的 UI 是真正原生控件。


RN 通信全过程

假设:

<Button
    title="登录"
    onPress={login}
/>

点击按钮。

整个流程:

Native Button

↓

点击事件

↓

Bridge

↓

JS

↓

login()

↓

axios()

↓

拿到数据

↓

setState()

↓

React Diff

↓

Bridge

↓

更新 Native View

完整流程:

Native

↓

Bridge

↓

JS

↓

React

↓

Bridge

↓

Native

Bridge 两边都能通信。


RN 更新 UI 原理

例如:

<Text>{count}</Text>

第一次:

count = 0

React:

<Text>0</Text>

Bridge:

Create Text

text="0"

Native:

UILabel

text = "0"

后来:

setCount(1)

React:

发现:

0

↓

1

Diff:

只更新:

text

Bridge:

发送:

UpdateText

id=3

text="1"

Native:

UILabel.setText("1")

不会整个页面重建。


JS 调 Native

例如:

调用摄像头:

NativeModules.Camera.open()

流程:

JS

↓

Bridge

↓

CameraModule

↓

Java

↓

Camera API

执行完成:

Java

↓

Bridge

↓

Promise Resolve

↓

JS

JS:

const result = await Camera.open();

Native 调 JS

例如:

扫码完成。

Android:

Camera

↓

识别二维码

↓

Native Module

↓

Bridge

↓

emit()

JS:

DeviceEventEmitter.addListener(
    "scanSuccess",
    (data)=>{
        console.log(data)
    }
)

流程:

Native

↓

Bridge

↓

JS Event

↓

回调

为什么 Bridge 慢?

Bridge 最大问题:

序列化(Serialization)

例如:

JS:

{
    name:"Tom",
    age:18
}

发送给 Native:

需要:

Object

↓

JSON

↓

Bridge

↓

JSON

↓

Java Object

反过来也一样。

所以:

每次通信都有:

  • 序列化

  • 反序列化

  • 拷贝

如果:

60fps

每一帧:

Bridge

↓

几千条消息

Bridge 就容易成为性能瓶颈。

尤其:

  • 大列表

  • 高频动画

  • 手势

  • 图表

  • 视频

都会卡顿。


新架构(JSI)

React Native 0.68+ 开始逐步采用新架构:

        JS
         │
     JSI(C++)
         │
 ┌───────┴────────┐
 │                │
Fabric        TurboModules
 │                │
 Native UI    Native Module

与 Bridge 相比:

  • 无需 JSON 序列化,JS 可通过 JSI 直接访问 C++ 层对象。

  • 支持同步调用,不再局限于异步消息队列。

  • 通信开销更低,减少跨语言拷贝。

  • 更适合高频场景,如动画、手势、复杂渲染等。


面试回答模板

可以按下面的思路概括:

React Native 经典架构由 JS 层、Bridge(桥接层)和 Native 层组成。JS 层负责 React 组件和业务逻辑,Native 层负责真正创建和渲染 Android/iOS 原生控件,Bridge 作为两者之间的通信通道,通过消息队列传递模块、方法和参数,实现 JS 调用原生能力以及原生回调 JS。由于 Bridge 需要进行数据序列化和反序列化,并且通信主要是异步的,因此在高频交互场景下容易成为性能瓶颈。为了解决这一问题,新架构引入了 JSI、Fabric 和 TurboModules,使 JS 能够更高效地与原生交互,降低通信成本并提升渲染性能。

这套回答既覆盖了经典 Bridge 架构,又点出了新架构的改进方向,是 React Native 面试中比较完整且常见的答法。

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐