2019-03-07
本文源链接为 React Native Internals,我将其翻译为中文。
React Native 是一个允许开发者使用 JavaScript 构建原生应用的框架。
等等!Cordova 不是很早就这么做了吗。为啥要用RN, 有啥特别的?
RN 与基于 Cordova 的应用的主要差别在于:
首先,直观会设想的是 React Native 将 JS 代码编译到对应的原生代码。
但是这很难实现,因为 Java 和 Objective C 都是强类型语言,而 JavaScript 是弱类型的。
React Native 没有这么做,而是通过一种更聪明的方式。
从本质上,React Native 可以看做是一组 React 组件,其中每个组件对应于相应的视图和组件。
例如,一个原生的 TextInput 会有一个 RN 组件与之对应,可以在 JS 中直接导入,就像使用普通 React 组件一样。
因此,开发者可以向开发普通 React Web APP 那样来开发原生应用。
好吧,这看起来像是黑魔法 🙄。
为了理解其中原理,让我们看看 React Native 的架构与内部工作方式。
iOS 与 Android 的架构是类似的,但是有细微差异。
如果我们从整体来看,RN 平台主要分为三部分:
Native Code/Modules:
Javascript VM:
React Native Bridge:React Native Bridge 是 C++/Java bridge,负责 Native 线程与 Java 线程间的通信。使用定制的协议传递消息。
在大多数情况下,开发者会使用 JavaScript 来编写整个应用。
通过以下命令行语句来运行程序:
react-native run-ios
react-native run-android
此时,React Native Cli 会创建一个 node 打包器(metro bundler),它会将 JS 代码打包为一个单个的 main.bundle.js 文件。
这个打包器可以被看做是类似 Webpack。
现在,当 React Native 应用被启动时,首先被加载的是原生入口点(native entry point)。
Native 线程会创建 JS VM 线程,并运行打包后的 JS 代码。JS 代码中包含应用的所有业务逻辑。
Native 线程现在通过 RN Bridge 发送消息,来启动 JS 应用。
指令包括加载哪些视图,从硬件中获取哪些信息等等。
例如,如果 JS 线程想要创建一个 VIew 和 Text,它会将请求打包为一个单条的消息,发送到 Native 线程并进行实际展示。
[ [2,3,[2,'Text',{...}]] [2,3,[3,'View',{...}]] ]
Native 线程会处理这些操作,并将结果返回给 JS,以确保操作已被完成执行。
注意:如果想在 Console 中查看 bridge 消息,只需要在 index.<platform>.js
中加入以下代码:
import MessageQueue from 'react-native/Libraries/BatchedBridge/MessageQueue'; MessageQueue.spy(true);
当 React Native 应用被启动时,它会创建一下线程队列:
链接:https://www.youtube.com/watch?v=0MlT74erp60
View Managers 是 Native Module,它将 JSX 视图映射到 Native Views。例如:
import React, { Component } from "react"; import { Text, View, AppRegistry } from "react-native"; class HelloWorldApp extends Component { render() { return ( <View style={{ padding: 40 }}> <Text>Hello world!</Text> </View> ); } } export default HelloWorldApp; AppRegistry.registerComponent("HelloWorldApp", () => HelloWorldApp);
其中:
<Text/>
,如果实在 Android 平台,Text View manager 会调用 new TextView(getContext())
在 Android 平台,View Managers 都是继承自 ViewManager
的类,在 iOS 则是继承自 RCTViewManager
。
当 APP 在 DEV
模式运行时 JavaScript 线程在开发机(电脑)上被创建。
尽管 JS 代码在电脑上运行的性能比手机上高,但是你会注意到实际性能比 bundled 模式或者 production 模式还要慢。
这是因为在 DEV模式下,在运行时要做许多额外工作,来提供更好的警告与错误信息,例如验证 propTypes 以及其它的断言。
此外,设备与 JS 之间的通信延迟也是导致慢的原因。
链接:https://www.youtube.com/watch?v=8N4f4h6SThc - RN android architecture
React Native 团队目前正在为 React Native 开发一个新架构。
新架构的代号为 Fabric,将会允许 React Native 以同步方式执行高优先级的 UI 更新。
这意味着 UI 在某些极限情况(Edge Cases)下会更灵敏(比如滚动视图)。
想要了解 Fabric 以及它到底如何提升 React Native 的话,请观看 Parashuram N 在 React Conf 2018 上的精彩演讲。https://www.youtube.com/watch?v=UcqRXTriUVI