React Native 技术原理:从 TypeScript 到原生界面、Fabric 与 Hermes

8月 10, 2026
Frontend, React, TypeScript, ByAI

AI 参与说明(Agent:Codex、Anscombe):本文由 Agent 根据 React Native、Hermes、Metro、Apple 与 Android 的官方公开文档协助整理,重点核对新架构、构建管线、测试和发布边界。资料核验于 2026-08-10;版本、构建工具和商店规则会变化,请以文末官方链接和项目实际版本为准。所有标识、密钥与账号均为占位示例。

适用范围:本文面向已经会 React / TypeScript、希望理解 React Native 运行原理的开发者。它以 React Native 0.86 为资料快照;Expo 如何组织 React Native 项目、CNG 与 EAS 如何交付,请阅读 Expo 技术原理与交付

先说结论#

React Native 是用 React 描述界面、再把宿主组件渲染为 iOS / Android 平台视图的框架。它不是把网页放进 WebView,也不会把普通 .tsx 业务源码逐行翻译成 Swift、Kotlin 或 ARM 机器码。

更准确的模型是:

TypeScript / JSX
  → Babel / Metro 转换与打包
  → Hermes 执行 JavaScript(release 通常使用 Hermes bytecode)
  → React + Fabric 形成和提交 Shadow Tree
  → Yoga 计算布局
  → UI thread 挂载 / 更新 iOS、Android Host Views

与此同时,原生侧是另一条独立编译链:Swift / Objective-C / C++ 由 Xcode 编译,Kotlin / Java / C++ 由 Gradle / NDK 编译。最后,JavaScript bundle / bytecode、原生库、图片字体和签名材料一起组成 iOS 的 .xcarchive / 可导出的 .ipa,以及 Android 的 .aab.apk共享的是多数 React / TypeScript 源码,不是一份跨平台二进制。

截至本文整理日,React Native 0.86 是官方 stable 线;0.82 起运行时只使用 New Architecture,0.84 起 Hermes V1 默认启用。不要跟随更早教程去关闭 newArchEnabled;Hermes 是默认且与 React Native 版本配套的 engine,无需另装,仍可按官方指引切换 JavaScriptCore。React Native versions React Native 0.82 React Native 0.84 Using Hermes

1. 先建立概念地图#

概念它是什么不是什么
React Native用 React 构建原生应用的框架WebView 容器、两套原生业务代码生成器
MetroReact Native 的 JS / 资源 bundlerSwift / Kotlin 编译器、模拟器
Babel把 JSX、现代 JS / TS 语法转换为可执行 JS 的转换器TypeScript 类型检查器的替代品
Hermes针对 React Native 优化的 JavaScript enginebundler、UI renderer、通用 ARM 编译器
FabricNew Architecture 的 rendererJavaScript engine、导航库
Shadow TreeFabric 用 C++ 表示的不可变渲染树DOM、最终原生 View 树
Yoga可移植的 Flexbox 风格布局 engine浏览器完整 CSS、Auto Layout / ConstraintLayout
JSIJS engine 与 C++ / 原生边界交互的接口“零成本、所有调用同步”的保证
TurboModuleNew Architecture 下的非 UI 原生能力模块任何页面组件、自动生成的原生实现
Codegen从受约束的 TS / Flow spec 生成跨边界 glue / 接口把所有 TS 业务逻辑变成原生代码
Fabric Native Component将原生 View / 控件暴露给 React 的方案普通函数组件的必经步骤

如果记不住全部名词,先记三个职责:Metro 打包,Hermes 跑 JS,Fabric 显示 UI。

2. 两条构建管线:开发与 Release#

开发态#

开发时,Metro 运行在本机,解析依赖、通过 Babel 转换 JSX / TS 语法、生成 bundle 并把它提供给 Debug 原生壳;设备上的 Hermes 执行代码,Fast Refresh 尽可能保留界面状态并重载已修改模块。

App.tsx / *.ts
  → Babel 转换(类型不会进入运行时)
  → Metro:Resolution → Transformation → Serialization
  → Debug App 通过网络读取 bundle / assets
  → Hermes 执行 → Fabric 更新 Host Views

Metro 还会按平台解析文件,例如 Button.ios.tsxButton.android.tsxButton.native.tsx,并处理图片等 assets。它不负责签名或编译 Swift / Kotlin。Metro concepts Metro resolution

Release / 上架态#

Release 构建将 JS bundle 与 assets 内置进 App。当前 Hermes 配置下,构建会将 JavaScript 预编译为 Hermes bytecode;这个产物仍由 JavaScript engine 执行,不应称为“把业务代码 AOT 成 iOS / Android CPU 机器码”。

flowchart TB
  subgraph JS["JavaScript 链"]
    A["TypeScript / JSX"] --> B["Babel"]
    B --> C["Metro bundle + assets"]
    C --> D["Hermes bytecode(Release)"]
  end

  subgraph Native["原生链"]
    E["Swift / ObjC / ObjC++ / C++"] --> F["Xcode"]
    G["Kotlin / Java / C++"] --> H["Gradle / NDK"]
  end

  D --> I["签名 iOS archive / .ipa"]
  F --> I
  D --> J["签名 Android .aab / .apk"]
  H --> J

TypeScript 在普通 bundle 中主要提供类型安全:Babel 会移除类型,tsc --noEmit 应独立用于类型检查。例外是 Codegen spec:构建工具会读取它受约束的 TypeScript / Flow 类型,生成 C++ glue 及 Java / Objective-C++ scaffolding / interfaces;这并不意味着任意业务 TS 会生成 Swift / Kotlin 实现。React Native TypeScript React Native Gradle Plugin

3. 最小运行示例:哪些节点会变成原生视图#

先按官方 Community CLI 创建一个没有框架层的项目:

npx @react-native-community/cli@latest init AwesomeProject --version 0.86
cd AwesomeProject
npm start

这条命令固定的是本文的版本快照;仍须先按 React Native 环境配置 安装 Node、JDK、Android Studio,以及 iOS 所需的 macOS / Xcode。

另开一个终端运行 Android,或在 macOS 上运行 iOS:

npm run android
npm run ios

App.tsx 改为:

import { useState } from "react";
import { Pressable, StyleSheet, Text, View } from "react-native";

export default function Counter() {
  const [count, setCount] = useState(0);

  return (
    <View style={styles.screen}>
      <Text accessibilityRole="header">Count: {count}</Text>
      <Pressable
        accessibilityRole="button"
        onPress={() => setCount((value) => value + 1)}
        style={styles.button}
      >
        <Text>Increment</Text>
      </Pressable>
    </View>
  );
}

const styles = StyleSheet.create({
  screen: { flex: 1, alignItems: "center", justifyContent: "center", gap: 12 },
  button: { borderRadius: 8, backgroundColor: "#dbeafe", padding: 12 },
});

预期结果是一个可点击计数器。这里的 Countercomposite component:它本身不会获得一个对应的原生 View。React 会继续归约 CounterPressableViewText 等 Host Component 才创建 Shadow Node 并进入 Fabric 的原生渲染链。Pressable 是交互抽象,最终由 View 等宿主组件承载,不应理解为额外且稳定的一对一原生视图。Pressable

4. Hermes:JavaScript 到底在哪里运行#

Hermes 是 React Native 默认使用、并与 React Native 版本绑定测试的 JavaScript engine。官方说明指出,许多应用能借此改善启动时间、内存使用和包体,但效果必须在真实 release 构建上测量,不能把“使用 Hermes”当作性能保证。Using Hermes Bundled Hermes

它在这里负责:

  1. 在设备上执行 React、业务逻辑、定时器与大部分 JS 事件处理;
  2. 在 Release 构建中加载预编译的 Hermes bytecode,减少设备启动时的解析工作;
  3. 为 JSI 提供可嵌入、可与 C++ 交互的 JavaScript runtime。

负责:解析 npm 依赖(Metro 负责)、绘制原生 UI(Fabric / 平台负责)、把每个 JS 函数改写成 Swift / Kotlin、替代 Xcode / Gradle。

可用下列代码确认当前 runtime 是否暴露 Hermes 标记,但不要只凭它判断 bytecode 是否按最佳方式加载;性能判断仍应跑 release benchmark:

export const isHermes = () => Boolean(global.HermesInternal);

开发版和生产版行为不同。官方建议用 release mode 对比 Hermes:

npm run android -- --mode="release"
npm run ios -- --mode="Release"

5. Fabric:React 怎样显示为 iOS / Android 界面#

Fabric 的核心渲染流程是 Render → Commit → Mount。它解释了为什么 React Native 既有 React 的声明式更新,又能更新平台视图。

flowchart LR
  A["Hermes 执行 React"] --> B["React Element Tree\nJavaScript"]
  B --> C["React Shadow Tree\nC++ / Fabric"]
  C --> D["Commit\nYoga 布局 + tree promotion"]
  D --> E["C++ diff + View Flattening"]
  E --> F["原子 mutation\ncreate / update / remove"]
  F --> G["UI thread Mount"]
  G --> H["iOS / Android Host Views\n由 OS 绘制"]

Render:从 React Element 到 Shadow Node#

React 在 JS 中运行函数组件并形成 Element Tree。Fabric 会为 Host Component 创建 C++ Shadow Node;函数组件、业务组件、Hooks 不是 Host View,因此不会一一对应 Shadow Node。Shadow Tree 保存 Host Component 的类型、props、children 与布局信息;普通 React / Hooks state 仍由 React 管理,只有少数宿主组件另有 C++ State。它以不可变结构支持线程安全更新。Render, Commit, and Mount

Commit:Yoga 计算布局#

Commit 阶段把新 Shadow Tree 作为待挂载树,并让 Yoga 计算大多数节点的尺寸和位置。Yoga 是可移植 C++ 布局 engine,使用 Flexbox 风格规则;它既不是浏览器 CSS 的完整实现,也不是 iOS Auto Layout 或 Android ConstraintLayout。

浏览器 CSS 与 React Native Flexbox 的默认值有差异,例如 React Native 的 flexDirection 默认 columnflexShrink 默认 0。把 Web 样式照搬到移动端前应先核对这些差异。React Native Flexbox Yoga

文本、文本输入等尺寸有平台相关部分,Yoga 可以请求宿主平台测量;因此不要承诺所有布局永远只在 C++ 内完成。

Mount:在 UI thread 修改 Host Views#

Fabric 在 C++ 中对已渲染树和下一棵树做 diff,产生 createViewupdateViewremoveViewdeleteView 等原子 mutation;平台 UI thread 再把它们应用到 Host View 上。Android 可对应 ViewGroupTextView 等,iOS 由 UIView 和平台文本系统承载。具体实现可能是 React Native 专用子类或组合,不应粗暴等同为“每个 JSX 都是一个 stock UIKit / Material 控件”。

View Flattening 会去掉或合并某些只用于布局的节点,减少原生 View 数量。因此“1 个 React 组件 = 1 个原生 View”有两层错误:函数组件本来不创建 Host View;布局节点也可能被 flatten。View Flattening

6. New Architecture:JSI、TurboModules 与 Codegen#

New Architecture 是一组协作机制,而不是一个“性能开关”。关键组成包括新 renderer(Fabric)、新原生模块系统(TurboModules)、JSI、Codegen 与新的 event loop 工作。它为同步布局访问、并发 React 特性和更直接的 JavaScript / 原生交互创造条件;官方也明确指出,启用新架构不会自动让每个 App 更快。New Architecture is here React Native 0.82

JSI:减少旧 Bridge 的固定序列化模型#

旧 Bridge 以异步、批量、序列化消息为主要模型。JSI 是轻量 C++ 接口,使 JS engine 可以直接持有 / 交互 C++ 对象引用,移除这一固定 JSON 序列化桥的依赖。

这不等于“没有成本”:对象转换、线程调度、平台 API、I/O、内存复制和错误处理仍可能昂贵;同步 API 也不应该拿来阻塞 JavaScript 或 UI 线程。更准确的说法是:JSI 改善跨边界的能力与模型,但性能要按具体调用路径测量。 React Native glossary

TurboModules:给非 UI 原生能力建立类型契约#

TurboModule 适合存储、设备 API、音频、数据库等非 UI 原生能力。它可延迟加载,并通过受约束的类型契约与 Codegen 接入。下面是一个缩短后的 spec;它本身还不能工作,因为 Android / iOS 实现尚未编写:

// specs/NativeLocalStorage.ts
import type { TurboModule } from "react-native";
import { TurboModuleRegistry } from "react-native";

export interface Spec extends TurboModule {
  setItem(value: string, key: string): void;
  getItem(key: string): string | null;
  removeItem(key: string): void;
  clear(): void;
}

export default TurboModuleRegistry.getEnforcing<Spec>("NativeLocalStorage");

配套包配置让 Codegen 知道在哪里找 spec:

{
  "codegenConfig": {
    "name": "NativeLocalStorageSpec",
    "type": "modules",
    "jsSrcsDir": "specs",
    "android": {
      "javaPackageName": "com.nativelocalstorage"
    },
    "ios": {
      "modulesProvider": {
        "NativeLocalStorage": "RCTNativeLocalStorage"
      }
    }
  }
}

Codegen 随 iOS / Android 构建生成接口与 glue;开发者仍须分别实现 Android 端,以及 iOS 或共享 C++ 端的业务能力,并在两端真机测试。本例的 iOS provider 使用 Objective-C++;若主体逻辑写在 Swift 中,仍需 Objective-C++ adapter。新增或修改 spec / codegenConfig 后,应在 ios/ 目录运行 bundle exec pod install,使 Codegen 重新生成并接入产物。完整教程见 Turbo Native Modules TurboModules with Swift

Fabric Native Component:当你要包一个原生 View#

若要把一个平台 UI 控件、原生地图 / 视频 / 相机预览 Surface 暴露给 React,则使用 Fabric Native Component。它与 TurboModule 的区别是:前者要参与 UI 树和 props / events,后者主要提供非 UI API。先评估已有成熟库,只有组件本身是产品差异化或 SDK 无合适封装时才自建。Fabric Native Components

兼容与旧库#

从 0.82 起不能切回 Legacy Architecture;但 React Native 仍有 Interop Layer 帮助部分旧库逐步过渡。不要把“Bridge 移除”写成“所有旧代码和所有兼容层已经不存在”,也不要因为 New Architecture 就跳过依赖兼容性测试。New Architecture is here React Native 0.84

7. 调试、性能与测试#

调试分工#

问题优先工具原因
React state、JS exception、breakpoint、JS heap / 对象生命周期、组件树React Native DevTools它连接设备内 Hermes runtime,适合 JS / React 层
原生崩溃、Swift / Kotlin、JNI、原生 UI、CPU / GPUXcode Instruments、Android Studio Profiler / System Trace需要看平台线程、符号和原生调用栈
Release JS stack与该构建严格匹配的 source map、metro-symbolicate生产 bundle 已转换 / 压缩,不能拿任意本地源码猜测

早期“在 Chrome 中远程运行 JavaScript”的资料已经过时;Remote JavaScript Debugging 自 React Native 0.79 起已移除。React Native DevTools 和原生 IDE 应各司其职;native heap / allocation 则继续使用 Instruments 或 Android Studio Profiler 查看。React Native DevTools Other debugging methods Debugging native code Debugging release builds

性能:先定位在哪一层掉帧#

60 Hz 设备每帧约有 16.67 ms;120 Hz 设备预算更小。不要笼统说“React Native 卡”,先区分:

  • JS / React 层:昂贵计算、过大 re-render、同步循环、日志和状态放置不当;
  • UI / main thread:频繁视图 mutation、复杂测量、导航动画、触摸响应;
  • GPU / 图形:大图、透明叠加、阴影、频繁缩放 / 重绘;
  • 列表 / 资源:过多 item、无稳定 key、图片解码、网络和缓存;
  • 启动 / 内存:初始 bundle、同步初始化、第三方 SDK、长期持有大对象。

应在 release / profile 构建、代表性真机、低端 Android 和目标 iPhone 上测量。开发模式的警告与调试负担会显著改变 JS 性能,不能以它作为生产结论。长列表优先 FlatList,固定高度项目可评估 getItemLayout,并在真实数据下权衡填充率、响应和内存。React Native performance Optimizing FlatList

测试金字塔#

  1. tsc --noEmit、lint:类型与静态问题;
  2. Jest:纯函数、领域逻辑、错误模型;
  3. React Native Testing Library:从用户可见文本、role、交互验证组件;
  4. 原生模块双端集成测试;
  5. 模拟器 / 真机 E2E:登录、支付、深链、推送、离线等关键旅程;
  6. release smoke:最终签名二进制、商店测试轨道与监控。

React Native 官方已提示 React Test Renderer 已废弃;Node 中的组件测试不执行 iOS / Android backing code,不能取代 E2E 与真机验证。E2E 可选 Detox、Appium、Maestro 等生态工具,不应写成 React Native 内置能力。Testing overview

React Native 0.85 起,Jest preset 已从 react-native 移到 @react-native/jest-preset。0.86 项目可使用:

module.exports = { preset: "@react-native/jest-preset" };

React Native 0.85

8. 发布:React Native 仍是原生发布流程#

Android#

  1. 确定 application ID、versionCode / versionName,并生成 / 保管 upload keystore;
  2. 在 Gradle 配置 release signing;
  3. 本地 release smoke 可用 npm run android -- --mode=release 安装 release APK;
  4. 发布 App Bundle 可运行 npx react-native build-android --mode=release,或在 android/ 下运行 ./gradlew bundleRelease
  5. bundletool 做本地安装与设备适配验证;再将 .aab 上传到 Play Console 的 Internal / Closed 等轨道,验证 Play App Signing、商店处理与分发链路,随后完成 Data safety、内容分级、商店资料与正式发布设置。

Google Play 新应用以 .aab 发布;其他商店或本地分发可使用 .apk,以当时规则为准。Play App Signing 负责面向用户的分发签名;upload key 与应用分发 key 的角色要分开理解。React Native 只帮你生成 App,不替代 Play 开发者账号、身份验证、测试门槛与审核。Signed APK / App Bundle Android App Signing

iOS#

  1. 在 macOS / Xcode 配置 Bundle ID、Apple Team、签名、权限用途文案与 Release scheme;
  2. 用 Release 配置构建,确保 JS bundle 被内置;
  3. 选择 Xcode 的 Product → Archive,再 Validate / Distribute / Upload;
  4. 在 App Store Connect 等待处理,使用 TestFlight 测试;
  5. 补齐 metadata、截图、隐私信息、审核账号和 Review Notes,再提交 App Review。

iOS 原生构建仍需 macOS / Xcode。免费 Apple Account 可用于有限的本机设备开发;TestFlight 与 App Store 分发需要 Apple Developer Program。账号、签名、Archive / TestFlight / App Review 流程与 Swift App 相同;React Native 还需确保 JS / Hermes bundle、Pods / 原生依赖与 Codegen 产物进入 archive,并另行生成、保留和上传与该构建严格匹配的 source map。Publishing to Apple App Store Debugging release builds Apple Developer Program

9. 常见误解核对表#

误解更准确的说法
RN 等于 WebViewFabric 渲染平台 Host Views,不依赖浏览器 DOM
TS 会变成 Swift / Kotlin / ARM普通 TS 经 Babel / Metro 进入 JS bundle;Release 常为 Hermes bytecode
Hermes 是 UI rendererHermes 跑 JS;Fabric 渲染 UI;Metro 打包
JSI 没有任何开销它改变跨边界模型,但仍有转换、线程、I/O 与平台成本
Codegen 自动写好原生功能Codegen 生成契约 / glue,原生实现仍需开发和测试
一个 JSX 一定对应一个 native Viewcomposite component 没有 Host View,layout-only 节点还可能 flatten
Yoga 就是完整 CSSYoga 是有限的 Flexbox 风格布局 engine,默认值也不同
New Architecture / Hermes 自动解决性能必须在 release 版本定位具体 JS、UI、GPU、资源或网络瓶颈
Fast Refresh 后永远不用重新编译改 JS 常可刷新;改原生依赖、Codegen、配置或原生代码要 rebuild
React Native DevTools 替代原生 IDE原生崩溃和平台性能仍需要 Xcode / Android Studio
一次构建同时上双端iOS / Android 分别编译、签名、上传、测试和审核

延伸阅读#

参考资料#

本文共 6503 字,上次修改于 Aug 10, 2026,以 CC 署名-非商业性使用-禁止演绎 4.0 国际 协议进行许可。

相关文章

» Expo 技术原理与交付:从 React Native 项目到 EAS 发布

» Expo、React Native 与 Flutter:概念、架构、上架与选型

» React Native 组件库横评:HeroUI Native、Paper、Tamagui 与 gluestack-ui

» 全面掌握 TanStack Query:现代 React 应用的数据管理利器

» 全面掌握 tRPC:端到端类型安全的下一代 API 框架