React Native 架构:Bridge → JSI → Hermes 与 New Architecture
0. 元信息
- 主题路径:
docs/topics/mobile-cross-platform/subtopics/react-native-architecture/README.md - 父主题:
mobile-cross-platform - 主分类:前端与客户端
- 辅助分类:工程技术
- 适合对象:写过 React + TypeScript、想理解 RN New Architecture 的开发者
- 建议周期:1~2 周(每周 8~12 小时,含真机调试与架构追踪)
- 前置知识:
mobile-cross-platform父主题;native-mobile-foundations;React Hooks、TypeScript、Metro - 最终目标:能讲清 Bridge → JSI → Hermes → Fabric → TurboModules 的演进,并在 RN 0.74+ New Architecture 下用 Codegen 写自定义 TurboModule
1. 学习路线
RN 起源与 Bridge 历史(async JSON 序列化)
→ Hermes 字节码与启动优化
→ JSI:JS 直调 C++ 与原生(同步调用)
→ Fabric:新渲染管线(UI 主线程 + 同步布局)
→ TurboModules:懒加载 + Codegen
→ New Architecture 启用与迁移
→ Expo 与 EAS Build 关系
→ RN 性能调优(Reanimated / FlashList / MMKV)
2. 阶段周数分配(46 周,每天 1.52 小时)
精简子主题按”运行时 → 渲染 → 模块 → 工具链”四阶段推进,再加一个综合周。
| 阶段 | 主题 | 周数 | 备注 |
|---|---|---|---|
| 1 | RN 起源与 Bridge 局限 | 0.5 周 | 历史包袱理解 |
| 2 | Hermes 与启动优化 | 1 周 | 字节码 + 内存 |
| 3 | JSI 与 Fabric 渲染管线 | 1.5 周 | 同步调用 + UI 主线程 |
| 4 | TurboModules 与 Codegen | 1 周 | 懒加载 + 类型生成 |
| 5 | Expo / EAS 与发布 | 0.5 周 | OTA / Build |
| 6 | 性能调优与监控 | 1 周 | Reanimated / FlashList / MMKV |
| 7 | 综合项目(新架构 demo) | 1 周 | 含 README + 复盘 |
选 4 周方案时把第 5/6 阶段压成 1 周。每周留 0.5 天复盘。
3. 九阶段表
| 阶段 | 核心知识 | 实践产出 | 可观察学会标准 |
|---|---|---|---|
| 1 | RN 工程结构(metro / ios / android / src) | npx react-native init 跑通 | 能解释 metro.config.js 与 Babel 作用 |
| 2 | Hermes vs JSC | Hermes 字节码对比 | 能用 hermes-engine 看 HBC |
| 3 | Bridge 模型(async JSON) | 旧文档读一遍 + 在 console 看 bridge log | 能解释为什么 Bridge 在大列表卡顿 |
| 4 | JSI 直调 C++ | react-native-mmkv 源码 | 能解释 jsi::Runtime 与 HostObject |
| 5 | Fabric 渲染 | 跑一个含 FlatList 的 RN App,看 layout pass | 能解释同步布局与 old renderer 差异 |
| 6 | TurboModules + Codegen | 用 TS Spec 生成原生模块 | 能生成 iOS / Android stub |
| 7 | New Architecture 启用 | RCT_NEW_ARCH_ENABLED=1 pod install 跑通 | 真机启动比 Old 快 |
| 8 | Reanimated 3 worklet | 写一个 60fps 动画 | UI 线程跑动画,JS 线程卡顿不掉帧 |
| 9 | EAS Build 与 OTA | Expo EAS Build 提交一次 | 出 ipa / apk |
关键陷阱:用旧文档学 Bridge;忽略 Codegen;Reanimated worklet 当普通 JS 写;JS bundle 不拆包。
4. 第一周任务
| 日 | 任务 | 当天交付 |
|---|---|---|
| Day 1 | 装 Node 22+、Watchman、Ruby;用 npx @react-native-community/cli init 建工程;启用 Hermes | RN 0.74+ 工程 + 真机跑 |
| Day 2 | 写 FlatList 列表 + 网络 + 详情,启用 Hermes | 列表 Demo |
| Day 3 | 装 react-native-mmkv,对比 MMKV vs AsyncStorage 启动时间 | 启动时间对比 |
| Day 4 | 装 react-native-reanimated,写一个 useSharedValue / useAnimatedStyle 动画 | 60fps 动画 |
| Day 5 | 用 FlashList 替换 FlatList,喂 1 万条数据看帧时间 | FlashList vs FlatList 帧时间对比 |
| Day 6 | 启用 New Architecture:RCT_NEW_ARCH_ENABLED=1,真机跑 | New Arch 配置证据 |
| Day 7 | 步骤 A:跑通 RN 最小可用(列表 + 详情 + 动画 + 持久化);步骤 B:补齐 4 类边界(JS bundle 拆分、JS 线程阻塞、原生模块错误、Image 缓存) | RN Demo + 边界测试 |
5. 阶段通用验收
- 不看答案独立重写 RN 工程与 New Architecture 配置;
- 用自己的话解释 Bridge / JSI / Hermes / Fabric / TurboModules 各自解决什么问题;
- 画一张图:Old Arch vs New Arch 调用时序;
- 测试正常路径、JS 线程阻塞、原生模块抛错、图片加载失败;
- 至少准备 3 组自定义数据并贴出实际渲染;
- 记录冷启动、JS bundle 大小、内存峰值、P99 帧时间;
- 能修改既有 App 加 TurboModule、加 Reanimated、加 Codegen。
6. 最终验收
- 独立画出 Bridge → JSI → Hermes → Fabric → TurboModules 演进图;
- 完成至少 10 个 RN 实验;
- 在 New Architecture 下用 Codegen 写一个自定义 TurboModule;
- 能用 10 分钟讲清 New Architecture 比 Old 快在哪。
7. 综合项目
实现「RN 跨端 Todo」:列表 + 详情 + 离线持久化(MMKV)+ 动画(Reanimated)+ 原生模块(Codegen 写一个 iOS / Android 原生计数器)。成果合入父主题首选综合项目。
本主题贡献
RN New Architecture 把 Bridge 异步 JSON 换成 JSI 同步直调,把渲染换成 Fabric 同步布局,把模块换成 TurboModules 懒加载,三件事必须一次讲清。本子主题专门补齐”为什么 Codegen 不能手写”、“为什么 Reanimated worklet 不能写闭包”、“为什么 MMKV 比 AsyncStorage 快一个数量级”三个常被绕过的点,并把 Hermes 字节码与 New Arch 启用后的量化收益说清。
3 职责
- 用 TS Spec → Codegen → Swift / Kotlin stub 的流程,演示一个自定义 TurboModule(计数器),证明类型在单一源真相。
- 把 Hermes 字节码(
.hbc)与 JSC 对比,冷启动时间 + 内存 + 包体积三个维度出量化差异。 - 用 Reanimated 3 worklet + FlashList + MMKV 组合,演示 60 fps 动画与 1 万条数据列表的 P99 帧时间。
4 交付物
- 一份 RN 0.74+ 工程(启用 Hermes + New Arch +
RCT_NEW_ARCH_ENABLED=1),真机跑通,配 Codegen Spec 一份。 - 一份 TS Codegen Spec(
src/NativeCounter.ts)+ iOS Swift 实现 + Android Kotlin 实现,类型贯通,包含 iOSrequiresMainQueueSetup与 Android 线程约束。 - 一份 Reanimated worklet 动画 + FlashList 大列表 + MMKV 持久化 demo,含 Flipper Performance 截图与 P99 帧时间对照。
- 一份 Bridge vs JSI 时序图(Old async JSON vs New sync direct call),对比 FlatList 帧时间数据,证明 Fabric 同步布局收益。
3 指标
- 冷启动 < 1.2 s(启用 New Arch + Hermes vs Old Arch 对照)。
- 1 万条 FlatList → FlashList 后 P99 帧时间下降 ≥ 50%(Flipper Performance)。
- Codegen 类型错误在 build 期拦截率 100%(TS Spec 改一处,原生两端 stub 自动同步)。
React Native Documentation、React Native New Architecture、Callstack Blog、Software Mansion: Reanimated。复制前核对 LICENSE。
8. 推荐资料
React Native Documentation、React Native New Architecture、Callstack Blog、Software Mansion: Reanimated。复制前核对 LICENSE。
9. 学习资料汇聚(v0.3 自包含)
9.1 背景与动机
React Native 在 2015 年开源时,核心假设是「Web 开发者能写移动端」。Bridge 模型让 JS 与 Native 互调,但 JSON 序列化与异步队列在大型列表与高频动画场景下掉帧。2022 年 Meta 推出 New Architecture,把 Bridge 替换为 JSI(同步直调)、把渲染替换为 Fabric(同步布局)、把原生模块替换为 TurboModules(懒加载 + Codegen)。今天任何 RN 工程都建议直接启用 New Architecture。
9.2 概念地图
flowchart TB
JS[JS 线程] -->|async JSON| Bridge[Old Bridge]
Bridge --> Native[Native UI / Modules]
NewArch[New Architecture] --> JSI[JSI 同步调用]
JSI --> Cxx[C++ 桥接层]
Cxx --> Fabric[Fabric 渲染]
Cxx --> Turbo[TurboModules]
Turbo --> Native
Hermes[Hermes 字节码] --> JS
Codegen[Codegen] --> Turbo
Codegen --> Fabric
9.3 基础知识讲解
9.3.1 论文 / 规范
| 资料 | 用法 |
|---|---|
| Meta, React Native: A New Architecture | 设计概览 |
| Meta, JSI Spec | JS 直调 C++ 接口 |
| React Native Codegen | TS Spec → iOS / Android 桩 |
9.3.2 书
| 书 | 用法 |
|---|---|
| Emin Toprak, React Native in Action | 入门 |
| Frank van Puffelen, React Native Cookbook | 实战 |
9.3.3 博客 / 文档
| 资料 | 用法 |
|---|---|
| React Native Blog | 版本与新架构进展 |
| Callstack: React Native | New Architecture 案例 |
| Software Mansion: Reanimated | worklet 原理 |
| Shopify: FlashList | 大列表虚拟化 |
9.3.4 人物
| 人物 | 关注点 |
|---|---|
| Jordan Walke | React Native 起源 |
| Bartłomiej Plewnia | New Architecture 推进 |
| Nicolas Cote | Fabric 渲染 |
| Krzysztof Magiera | Reanimated |
9.3.5 方法
- Always enable New Architecture on greenfield:旧项目按模块迁移。
- Use Codegen for every new TurboModule:TS Spec 单源真相。
- Prefer Hermes:0.70+ 默认。
- Profile on real device:用 Flipper + React DevTools。
- Avoid
setNativeProps:走 Fabric 状态流。
9.3.6 重点训练材料
- React Native New Architecture 仓库讨论
- Hermes 源码与字节码格式
- React Native Fabric 源码
- Reanimated worklet 文档
9.4 经典问题与经典案例
| # | 问题 | 最简答案 |
|---|---|---|
| 1 | Bridge 卡顿 | 异步 JSON 序列化;用 JSI 替换 |
| 2 | Hermes 字节码如何预编译 | Metro transformer 输出 .hbc |
| 3 | JSI 怎么调原生 | jsi::Runtime 注册 HostObject |
| 4 | Fabric 怎么同步布局 | UI 主线程 + Yoga |
| 5 | TurboModule 怎么写 | TS Spec → Codegen → Swift / Kotlin 实现 |
| 6 | Reanimated worklet 怎么跑 | 'worklet' 指令 + UI 线程 |
| 7 | FlashList 为什么比 FlatList 快 | 双向缓存 + 回收 |
| 8 | MMKV 为什么比 AsyncStorage 快 | mmap + JSI |
| 9 | JS bundle 怎么拆 | Metro splitChunks |
| 10 | New Architecture 怎么启用 | RCT_NEW_ARCH_ENABLED=1 |
9.5 学习难点
| 难点 | 为什么会卡 | 突破路径 |
|---|---|---|
| Bridge vs JSI 思维模型 | 习惯异步 JSON | 读 Codegen 生成的 Native stub |
| Codegen 配置 | TS Spec 写错 | 用 react-native-codegen-typescript 校验 |
| Fabric 渲染时序 | 老资料讲 old renderer | 看 React Native 0.74+ 源码 |
| Reanimated worklet 边界 | 闭包捕获 UI 线程变量 | 用 runOnUI / runOnJS |
| New Arch 迁移 | 三方库不兼容 | 用 interop layer |
9.6 技术标准与接口
9.6.1 Entity
| 名称 | 版本 | 组织 | 状态 |
|---|---|---|---|
| React Native | 0.74+ | Meta + 社区 | 活跃 |
| Hermes | 0.12+ | Meta | 活跃 |
| Reanimated | 3.x | Software Mansion | 活跃 |
| FlashList | 1.x | Shopify | 活跃 |
| MMKV | 2.x | Tencent | 活跃 |
9.6.2 Scope
RN 负责 JS 渲染与跨端逻辑,原生模块负责系统调用。新架构把异步桥换成同步直调。
9.6.3 Structure
工程结构:android/ + ios/ + src/ + metro.config.js;TS Spec 文件:src/Native*.ts。
9.6.4 Ecosystem
Expo、React Navigation、Reanimated、FlashList、MMKV、Sentry、CodePush、EAS Build。
9.6.5 Depth Tiers
| 层级 | 能力 |
|---|---|
| L0 | 知道 RN / Bridge |
| L1 | 能读懂 RN 工程 |
| L2 | 能写 RN App + 持久化 + 导航 |
| L3 | 能用 New Architecture + Codegen |
| L4 | 能设计 TurboModule + Fabric 渲染策略 |
本子主题目标:L3。
9.6.6 Source
- React Native Documentation
- New Architecture discussions
- 引用版本快照日期:2026-07-30。
10. 常见误区
- 用旧文档学 Bridge;
- 不启用 Hermes;
- 不开 New Architecture;
- Codegen Spec 写错不校验;
- Reanimated 当 JS 动画写;
- FlatList 喂 1 万条数据不换 FlashList;
- AsyncStorage 当主存储;
- JS bundle 不拆;
- 不上真机调试;
- 不读 release notes。
11. 所有知识点分类(统一规则)
- 编程语言;2. 数据结构与算法;3. 计算机基础;4. 工程技术;5. Web 与后端;6. 前端与客户端;7. 数据与人工智能;8. 项目与职业能力;9. 安全与可靠性。
本计划归属:前端与客户端 主 + 工程技术 辅。
代码块 1:RN TurboModule Codegen Spec
// src/NativeCounter.ts
import type { TurboModule } from 'react-native';
import { TurboModuleRegistry } from 'react-native';
export interface Spec extends TurboModule {
increment(value: number): Promise<number>;
reset(): void;
}
export default TurboModuleRegistry.getEnforcing<Spec>('NativeCounter');
代码块 2:iOS 实现
// ios/Counter/Counter.swift
import Foundation
@objc(Counter)
public class Counter: NSObject {
@objc public func increment(_ value: NSNumber,
resolver resolve: @escaping RCTPromiseResolveBlock,
rejecter reject: @escaping RCTPromiseRejectBlock) {
resolve(value.intValue + 1)
}
@objc public func reset() {
// no-op
}
@objc public static func requiresMainQueueSetup() -> Bool { false }
}
代码块 3:Reanimated worklet
// src/AnimatedBox.tsx
import Animated, { useSharedValue, useAnimatedStyle, withSpring } from 'react-native-reanimated';
export function AnimatedBox() {
const x = useSharedValue(0);
const style = useAnimatedStyle(() => ({
transform: [{ translateX: x.value }],
}));
return (
<Animated.View
style={[{ width: 80, height: 80, backgroundColor: 'tomato' }, style]}
onTouchEnd={() => { x.value = withSpring(x.value + 100); }}
/>
);
}
代码块 4:Bridge vs JSI 时序
sequenceDiagram
participant JS
participant Bridge as Old Bridge
participant JSI as JSI (New Arch)
participant Native
Note over JS,Native: Old: Bridge 异步 JSON
JS->>Bridge: rpc("increment", 1)
Bridge-->>Native: 序列化 + 排队
Native-->>Bridge: 返回
Bridge-->>JS: Promise resolve
Note over JS,Native: New: JSI 同步
JS->>JSI: jsi.invoke("increment", 1)
JSI->>Native: 同步调用
Native-->>JSI: 返回
JSI-->>JS: 同步返回