
一、React Native是什么?
React Native是Facebook在2015年开源的移动应用开发框架,它允许开发者使用JavaScript和React语法来构建原生移动应用。RN的核心理念是"Learn once, write anywhere"(一次学习,随处编写),通过JavaScript Bridge与原生平台通信,最终渲染为真正的原生组件。
1.1 出现时机
2015年3月,Facebook 在 F8 开发者大会上正式发布了 React Native,这个时期正是移动互联网快速发展的阶段,移动应用开发需求激增。
1.2 解决的问题
- 跨平台效率问题,iOS和Android两套代码
- 开发维护成本高
- 基于React实现一次编写,到处运行的理念
1.3 H5 vs RN vs Flutter
为什么要这么对比呢,因为这三个代表了三种不同的技术流派:
- h5对应的是所有基于webview的技术方案
- RN对应的是逻辑JS + Native Runtime的技术方案
- Flutter是代表的是自绘引擎的技术方案
对比维度 | H5 | React Native | Flutter |
---|---|---|---|
技术特点 | |||
编程语言 | HTML/CSS/JS | JavaScript/TypeScript | Dart |
运行方式 | WebView容器 | JS Bridge + 原生组件 | 直接编译原生代码 |
UI渲染 | 浏览器渲染 | 原生组件渲染 | 自绘UI引擎 |
性能表现 | |||
启动速度 | 慢 | 中等 | 快 |
运行性能 | 较差 | 良好 | 优秀 |
动画流畅度 | 一般 | 流畅 | 非常流畅 |
内存占用 | 高 | 中等 | 较低 |
开发体验 | |||
学习成本 | 低 | 中等 | 中高 |
开发效率 | 高 | 高 | 高 |
热重载 | 即时刷新 | 支持 | 支持 |
调试工具 | 浏览器DevTools | Flipper/Chrome | Flutter Inspector |
生态与支持 | |||
生态丰富度 | 非常丰富 | 丰富 | 快速增长 |
第三方库 | 海量 | 较多 | 中等 |
社区活跃度 | 非常活跃 | 活跃 | 很活跃 |
大厂支持 | 全平台 | Meta/微软 | |
部署运维 | |||
更新方式 | 即时更新 | 热更新 | 发版更新 |
包体积 | 小 | 中等 | 较大 |
兼容性 | 浏览器兼容性 | iOS/Android | 跨多平台 |
维护成本 | 低 | 中等 | 中等 |
适用场景 | |||
内容展示 | ✅ 最佳 | ⚠️ 过度 | ⚠️ 过度 |
复杂应用 | ❌ 性能限制 | ✅ 适合 | ✅ 很适合 |
游戏开发 | ❌ 不适合 | ⚠️ 简单游戏 | ✅ 适合 |
快速原型 | ✅ 最快 | ✅ 快 | ✅ 快 |
成本考量 | |||
开发成本 | 低 | 中等 | 中等 |
人员要求 | Web前端 | 前端+移动端 | 需学Dart |
测试成本 | 低 | 中等 | 中等 |
1.4 成功案例
APP Store中 Top 100 iOS app选择的技术栈:x.com/search?q=re...
国外知名应用:
- Facebook、Instagram、WhatsApp (Meta系)
- Microsoft Office、Skype (微软系)
- Tesla、Uber Eats、Pinterest
- Discord、Shopify、Bloomberg
国内主要厂商:
- 字节跳动: 抖音、今日头条 (基于LYNX引擎)
- 腾讯: 微信,视频等
- 美团: 基于MRN框架
- 京东: 京东App部分模块
- 携程: 基于CRN框架
市场数据: 根据2024年统计,App Store Top 500应用中约有15%使用了React Native技术栈。
以上我们对比了不同的技术方案,那我们会好奇,RN是如何来做的呢,既能保持动态化,又可以保证性能呢?国内大厂例如,国外的微软,facebook,特斯拉,都是RN的重度使用用户为什么它是各个大厂动态化的基础呢?
二、动态化原理
RN的工作原理就像上面介绍的一样是,JS + Native渲染,渲染的节点从前端的dom元素,变成了原生的TextView, ImageView等原生View,这样开发者就只需要学习React即可开发,那对于我们移动端开发人员来说,我们就会好奇它是如何实现的呢?那我们就可以从这里入手来看下RN最核心的知识JS如何绑定Native渲染来看下吧。
2.1 简化版RN架构
说了这么多,都是基础结构知识,那有没有一种直观的方式让我们来了解整体RN的原理呢,正如Linus Torvalds所说:'Talk is cheap. Show me the code.'接下来我们将通过构建一个简化版的RN框架,来深入理解其核心工作原理。
主要参考资料和文章:
- 快手:打造自己的动态化引擎:juejin.cn/post/704629...
- 从0到1写一个React:pomb.us/build-your-...
我们可以从架构来看如何设计:

我们可以套用原来WebviewBridge的知识,那动态化需要一个桥用来连接js语言和Native语言,还要能执行js代码,那我们不依赖于webview的话就需要一个js虚拟机,这里我们选择的是QuickJS:github.com/taoweiji/qu...;
没有了webview的渲染,需要用Native渲染,那就需要一个Native渲染的Runtime,还要支持灵活注册
我们来看下我们示例的react代码,看看整体它是如何做的吧:
java
function App() {
return (
<View
style={{
flex: 1,
justifyContent: "center",
alignItems: "center",
backgroundColor: "#f5f5f5"
}}
>
<Text
onPress={() => {
console.info('文本被点击了!');
}}
style={{
fontSize: 24,
color: "#007AFF",
padding: 20
}}
>
点击我
</Text>
</View>
);
}
React.render(APP);
这里都是JSX语法,然后我们可以通过babel进行转换为一下代码:
java
function App() {
return /*#__PURE__*/React.createElement(View, {
style: {
flex: 1,
justifyContent: "center",
alignItems: "center",
backgroundColor: "#f5f5f5"
}
}, /*#__PURE__*/React.createElement(Text, {
onPress: () => {
console.info('文本被点击了!');
},
style: {
fontSize: 24,
color: "#007AFF",
padding: 20
}
}, "\u70B9\u51FB\u6211"));
}
React.render(/*#__PURE__*/React.createElement(App, null));
我们能看到其实这种标签写法就是语法糖,真正的调用方法是React.createElement。
从这里面我们可以看到我们需要解决两个问题,一个就是逻辑动态化,一个就是如何通过标签渲染为Native View,先来看看如何做逻辑动态化吧。
2.1.1 逻辑动态化如何做
我们是基于QuickJS来进行执行JS代码,它就像给webview写桥一样,本身就支持,具体教程在这里github.com/taoweiji/qu...
2.1.2 创建QuickJS环境
通过以上文档我们可以看到主要通过一下API来实现:
java
class JsContext {
// 创建一个引擎
private val mEngine = QuickJS.createRuntime()
private var mContext: JSContext? = null
init {
// 创建一个上下文,一个引擎可以创建多个,这里我们只用一个就好
mContext = mEngine.createContext()
}
fun getContext(): JSContext = mContext!!
fun runApplication(jsBundle: JsBundle) {
mContext!!.executeStringScript(jsBundle.mAppJavaScript, "test.js")
}
}
这样我么可以看到通过创建好引擎后,直接调用executeStringScript就可以执行JS代码
2.1.3 注入Native方法
那我们执行JS后就有一个问题,以console.info为例,它在JS侧没有定义的,需要通过native侧来注入,再来看下代码:
java
// 1.context就是我们上面创建的QuickJS的一个上下文
val consoleObj = JSObject(context)
// 2.具体的native侧方法
consoleObj.registerJavaMethod(object : JavaCallback {
override fun invoke(receiver: JSObject?, args: JSArray?): Any? {
printJSArray(args)
}
}, "info")
// 3.注入到console对象上
context.set("console", consoleObj)
// 4.具体实现逻辑
private fun printJSArray(params: JSArray?) {
if (params == null) return
val messages = mutableListOf<String>()
for (i in 0 until params.length()) {
try {
val value = params.getString(i) ?: "null"
messages.add(value)
} catch (e: Exception) {
messages.add("[object]")
}
}
Log.i("JSConsole", messages.joinToString(" "))
}
从以上代码上我们就可以看到我们实现了JS->Native的逻辑。
2.1.4 UI动态化-构建UI树
逻辑动态化我们上面就介绍完毕了,那如何实现UI动态化呢?从上面我们可以看到渲染和两个方法有关系一个是React.createElement另一个是React.render,React.render负责渲染,而React.createElement负责创建视图树,createElement已经给我们抽象好了固定为(类型+参数+child),那我们就实现这两个方法就好了
先来看下createElement如何实现吧
java
private fun createElement(params: JSArray?): JSObject? {
if (params == null || params.length() < 1) {
Log.e("ReactModule", "createElement requires at least 1 parameter")
return null
}
try {
// 1.要进行转换,创建一个vElement对象
val vElement = JSObject(jsContext)
// 组件类型
val type = params.getString(0)
if (type.isNullOrEmpty()) {
Log.e("ReactModule", "Component type cannot be null or empty")
return null
}
// 2.装配类型
vElement.set("type", type)
// props(可选)
val props = if (params.length() > 1) {
params.getObject(1) ?: JSObject(jsContext)
} else {
JSObject(jsContext)
}
// 3.装配参数
vElement.set("props", props)
// children
val children = JSObject(jsContext)
var childCount = 0
// 4.解析child
for (i in 2 until params.length()) {
val objectChild = params.getObject(i)
val stringChild = if (objectChild == null) params.getString(i) else null
when {
objectChild != null -> {
children.set(childCount.toString(), objectChild)
childCount++
}
stringChild != null -> {
children.set(childCount.toString(), stringChild)
childCount++
}
}
}
children.set("length", childCount)
// 5.装配child组件
vElement.set("children", children)
return vElement
} catch (e: Exception) {
Log.e("ReactModule", "Error creating element", e)
return null
}
}
从这里代码看出来我们就是在构建一个渲染树,构建渲染树结束后,js侧在调用render方法进行渲染,接着我们看下渲染树如何做吧。
2.1.5 UI动态化-渲染UI树
从上面我们可以知道我们已经构建了一个UI树,剩下render要做的事,就是渲染整颗树了。
java
private fun render(params: JSArray?): Any? {
try {
val vdom = params.getObject(0) ?: return null
//1.要基于Android侧根containerView来做
containerView?.let { container ->
renderer.renderRoot(vdom, container, jsContext)
return true
} ?: run {
Log.e("ReactModule", "Container not set")
return false
}
} catch (e: Exception) {
Log.e("ReactModule", "Error rendering virtual DOM", e)
return false
}
}
fun render(vElement: JSObject, parent: ViewGroup, jsContext: JSContext): View? {
try {
val type = vElement.getString("type")
if (type.isNullOrEmpty()) {
Log.e("VirtualDOMRenderer", "Element type is null or empty")
return null
}
val props = vElement.getObject("props")
val children = vElement.getObject("children")
//2.将视图树从JS转换为NativeView,支持View和Text
val renderer = RendererFactory.createRenderer(type, context)
if (renderer == null) {
Log.e("VirtualDOMRenderer", "No renderer found for type: $type")
return null
}
//4.触发真正的渲染
return renderer.render(props, children, parent, jsContext)
} catch (e: Exception) {
Log.e("VirtualDOMRenderer", "Error rendering virtual DOM element", e)
return null
}
}
//3.创建Text -> Native Text的映射
class TextRenderer(private val context: Context) : IComponentRenderer {
private val styleProcessor = TextStyleProcessor()
private val eventHandler = TextEventHandler()
override fun getSupportedType(): String = "Text"
//5.渲染Text
override fun render(props: JSObject?, children: JSObject?, parent: ViewGroup, jsContext: JSContext): View {
val textView = TextView(context).apply {
layoutParams = ViewGroup.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT
)
}
// 设置文本内容
children?.let { childrenObj ->
val lengthValue = try {
childrenObj.getString("length")?.toIntOrNull() ?: 0
} catch (e: Exception) {
0
}
if (lengthValue > 0) {
val text = childrenObj.getString("0")
textView.text = text ?: ""
}
}
// 应用样式
props?.getObject("style")?.let { style ->
styleProcessor.applyStyle(textView, style)
}
// 绑定事件
eventHandler.bindEvents(textView, props, jsContext)
return textView
}
}
// 6.JS中View组件相当于Android的ViewGroup,这个是将NativeView树整体串联的地方
override fun render(props: JSObject?, children: JSObject?, parent: ViewGroup, jsContext: JSContext): View {
val linearLayout = LinearLayout(context).apply {
orientation = LinearLayout.VERTICAL
layoutParams = ViewGroup.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT
)
}
// 应用样式
props?.getObject("style")?.let { style ->
styleProcessor.applyStyle(linearLayout, style)
}
// 渲染子组件
children?.let { childrenObj ->
val length = try {
childrenObj.getString("length")?.toIntOrNull() ?: 0
} catch (e: Exception) {
0
}
for (i in 0 until length) {
val child = childrenObj.getObject(i.toString())
child?.let { childElement ->
val childType = childElement.getString("type")
val childRenderer = RendererFactory.createRenderer(childType ?: "", context)
childRenderer?.let { renderer ->
val childProps = childElement.getObject("props")
val childChildren = childElement.getObject("children")
val childView = renderer.render(childProps, childChildren, linearLayout, jsContext)
linearLayout.addView(childView)
}
}
}
}
return linearLayout
}
2.1.6 效果
最终在页面上的效果就是如图所示:


以上我们就完整的实现了利用QuickJS+Native视图树渲染的流程,真正的ReactNative要复杂的多,但是ReactNative框架整体核心流程是如此的。
三、RN整体架构
RN发找到现在已经很庞大了,整体架构设计的部分有很多,简单看下整体RN的架构图,以及其中的核心技术点我们来看下:
技术组件 | 作用与职责 | 核心功能 |
---|---|---|
JavaScript Thread | ||
JavaScript Code/React Components | React组件和业务逻辑执行 | • 组件状态管理 • 生命周期处理 • 用户交互逻辑 • 数据处理和API调用 |
Fiber Reconciler | React的协调算法引擎 | • 虚拟DOM差异计算 • 可中断的渲染过程 • 优先级调度系统 • 时间切片(Time Slicing) |
React Native Framework | RN框架核心 | • 组件树管理 • 平台抽象层 • 事件系统封装 • 样式处理 |
JSI Layer | ||
JavaScript Interface (JSI) | JS与Native直接通信桥梁 | • 消除JSON序列化开销 • 同步函数调用 • 类型安全的绑定 • 内存共享机制 |
Hermes Engine | 专为RN优化的JS引擎 | • 字节码预编译 • 减少内存占用 • 提升启动速度 • 垃圾回收优化 |
Fabric (UI Layer) | ||
Codegen | 静态代码生成工具 | • TypeScript接口分析 • C++绑定代码生成 • 类型定义自动化 • 编译时错误检查 |
Shadow Tree | 平台无关的UI树结构 | • 跨平台布局抽象 • 差异算法优化 • 布局状态管理 • 并发渲染支持 |
Yoga Layout Engine | Flexbox布局计算引擎 | • CSS Flexbox实现 • 跨平台布局算法 • 约束求解 • 性能优化的C++实现 |
Background Thread | ||
Fabric Renderer | 新架构渲染器 | • Shadow Node创建 • 布局计算调度 • 树状结构差异对比 • 并发渲染管理 |
Layout Engine | 布局计算处理器 | • Measure阶段处理 • Layout阶段执行 • 约束条件求解 • 布局缓存优化 |
Main Thread (UI Thread) | ||
Mounting Layer | 平台视图挂载层 | • 原生View创建 • 视图更新应用 • 事件绑定管理 • 生命周期处理 |
Native Views | 平台原生视图组件 | • iOS UIView封装 • Android View封装 • 平台特性支持 • 原生动画集成 |
Event System | 事件处理系统 | • 触摸事件捕获 • 手势识别 • 事件冒泡处理 • 跨平台事件标准化 |
TurboModules | ||
TurboModule | 新一代原生模块系统 | • 懒加载机制 • 类型安全保证 • 更好的性能表现 • 同步/异步调用支持 |
Native Modules | 平台原生功能模块 | • 平台API封装 • 第三方库集成 • 设备功能访问 • 自定义功能扩展 |
四、后续RN参考文章链接
4.1 官方文档与资源
- React官方地址:react.dev/
- React Native官方地址:reactnative.dev/
- React Native中文网站:reactnative.cn/
- Metro构建工具:metrobundler.dev/
- Hermes JavaScript引擎:hermesengine.dev/
- Yoga布局引擎:yogalayout.com/
4.2 新架构相关
- 官方新架构指南:reactnative.dev/docs/the-ne...
- Fabric渲染器详解:reactnative.dev/docs/the-ne...
- 新架构迁移指南:reactnative.dev/docs/new-ar...
4.3 核心技术深度文章
- 快手:打造自己的动态化引擎:juejin.cn/post/704629...
- 从0到1写一个React:pomb.us/build-your-...
- React Fiber架构详解:github.com/acdlite/rea...
- JSI工作原理深度解析:formidable.com/blog/2019/j...
- React Native性能优化指南:reactnative.dev/docs/perfor...
- 理解React Native Bridge:hackernoon.com/understandi...
4.4 Skia渲染相关
- React Native Skia官方:shopify.github.io/react-nativ...
- Skia GitHub仓库:github.com/Shopify/rea...
- Skia渲染引擎介绍:skia.org/
4.5 大厂实践案例
- Meta RN团队博客:reactnative.dev/blog
- 微软RN实践,win + mac:microsoft.github.io/react-nativ...
- Airbnb的RN之路:medium.com/airbnb-engi...
- Discord的RN重构:blog.discord.com/how-discord...
- Shopify的RN实践:shopify.engineering/react-nativ...
4.6 YouTube技术视频
- React Native新架构详解 (Chain React 2018):www.youtube.com/watch?v=Ucq...
- 新架构:www.youtube.com/watch?v=BdP...
- Hermes引擎介绍:www.youtube.com/watch?v=zEj...
- React Native Skia实战:www.youtube.com/watch?v=W6y...
- Skia:www.youtube.com/watch?v=EHx...
4.7 开源项目与工具
- React Native主仓库:github.com/facebook/re...
- React核心仓库:github.com/facebook/re...
- Hermes引擎:github.com/facebook/he...
- Yoga布局引擎:github.com/facebook/yo...
- QuickJS Android:github.com/taoweiji/qu...
- React Native Elements:github.com/react-nativ...
- React Navigation:github.com/react-navig...
- expo: docs.expo.dev/
4.8 性能监控与调试
- Flipper调试工具:fbflipper.com/
- React Native Debugger:github.com/jhen0409/re...
- 性能监控最佳实践:reactnative.dev/docs/profil...
- 内存泄漏检测:reactnative.dev/docs/debugg...
4.9 热更新方案
- CodePush官方文档:docs.microsoft.com/en-us/appce...
- React Native热更新原理:github.com/Microsoft/r...
4.10 跨平台扩展
- React Native Web:necolas.github.io/react-nativ...
- React Native Windows:microsoft.github.io/react-nativ...
- React Native macOS:microsoft.github.io/react-nativ...
4.11 技术博客与社区
- React Native官方博客:reactnative.dev/blog
- 掘金RN专栏:juejin.cn/tag/React%2...