1000公里高空俯瞰 React Native

       感谢支持ayqy我的订阅号,每周义务推送1篇(only unique one)原创精品博文,话题包括但不限于前端、Node、Android、数学(WebGL)、语文(课外书读后感)、英语(文档翻译)        
       若是以为弱水三千,一瓢太少,能够去 http://blog.ayqy.net 看个痛快    
   前端

一.历史:React Native 从开始到如今

React Native 的定位是经过 React 构建原生 App:react

A framework for building native apps with React.web

具备 5 大特性:小程序

  • Create native apps for Android and iOS using React:用 React 建立 Android、iOS 应用微信小程序

  • Written in JavaScript—rendered with native code:写的是 JavaScript,实际渲染的是 Native 界面react-native

  • Native Development For Everyone:基于平台无关的基础组件开发,就能得到平台原生体验微信

  • Seamless Cross-Platform:无缝过渡,Native 代码可以包装成 React Native 可用的组件架构

  • Fast Refresh:改动当即生效,拥有 Web 同样的开发速度app

那么,有 2 个问题:less

  • 为何要用 React(或者说用 JavaScript)写 Native 应用?源动力是什么?

  • 为何以这种方式跨平台,而不是 WebView?

探索思路

之因此用 React 写 Native 应用,有 2 方面缘由:

  • React 自身的优点:声明式视图定义带来的 UI 可预测性、组件化机制下的复杂度拆解等

  • Web 开发的优点:快速迭代、快速反馈、快速开发

Native 用上 React 的话,也能得到 React 的种种好处。固然,这只是一方面,背后的真正源动力是但愿 Native 开发能像 Web 同样 move fast

而对于第二个问题,要从 React Native 的由来讲起

实际上,Facebook 尝试过 3 种思路:

  • WebView:由 Native 提供 Webview 容器,业务用 Web 技术来开发

  • Porting React to native:把 React 移植到 Native 实现

  • Scripting native:经过 JavaScript 调用 Native API

不利用低成本的 WebView 方案跨平台,是由于受限于 Web 技术,体验没法与 Native 相提并论,最终因性能和扩展性没有达到预期而做罢

把 React 移植到 Native 是个不错的思路,但只能得到 React 自身的一些好处(不包括 JavaScript 世界的 React 繁荣生态),而且无助于 Native 的 move fast,由于 Native 仍是纯 Native

相比之下,React Native 经过 JavaScript 调用 Native API 是一个一箭双鵰的方案,既能让 Native 用上 React(及 JavaScript 的繁荣生态),也能拥有 Web 的开发速度,由于写的和实际执行的都是 JavaScript,Native 仅提供视图渲染能力及平台特定能力

发展历程

React Native 诞生于 2013 年的 Facebook 内部黑客马拉松(hackathon)

2015 年 1 月的 React.js Conf 上,这个内部项目首次公布,并在 5 月的 F8 Conference 上正式开源。最初只支持 iOS,同年 9 月支持了 Android

2016 年提供的 Microsoft UWP 和 Samsung Tizen 支持,意味着 React Native 从移动端走向了 PC(Win 10)、游戏机(Xbox One)、手环(Gear Fit 2)、智能电视机(SUHD)甚至全息眼镜(HoloLens)

2018 年 6 月启动了架构升级计划 Fabric,重构线程模型并简化 React Native Core,以更好地支持 Native & React Native 混合 App

2019 年 7 月迎来 JavaScript 引擎级性能提高,将 Android 平台以前使用的 JavaScriptCore 替换成 Hermes

P.S.关于 React Native 发展史的更多信息,见React Native 简史

二.架构:原来,你是这样的 RN!

写的是 JavaScript,实际渲染的是 Native 界面

所以,从很是高的视角来看,能够这样理解 React Native 技术(或者说 Scripting Native 方案):

JavaScript层
---------------------------------
???
---------------------------------
Native层

关键点在于:中间是什么?上下两个世界是怎样联系起来的?

架构设计

在 React Native 里,中间是 Bridge 层,经过消息通讯将 JavaScript 世界与 Native 世界联系起来

具体的,Shadow Tree 用来定义 UI 效果及交互功能,Native Modules 提供 Native 功能(好比蓝牙),两者之间经过 JSON 消息相互通讯:

Bridge 层是 React Native 技术的关键,设计上具备 3 个特色:

  • 异步(asynchronous):不依赖于同步通讯

  • 可序列化(serializable):保证一切 UI 操做都能序列化成 JSON 并转换回来

  • 批处理(batched):对 Native 调用进行排队,批量处理

P.S.关于 React Native 架构的更多信息,见React Native 架构一览

线程模型

React Native 中主要有 3 个线程,分别是:

  • UI Thread:Android/iOS(或其它平台)应用中的主线程

  • Shadow Thread:进行布局计算和构造 UI 界面的线程

  • JS Thread:React 等 JavaScript 代码都在这个线程执行

此外,还有一类 Native Modules 线程,不一样的 Native Module 能够运行在不一样的线程中(具体见Threading)

启动过程

总体上,启动过程分为初始化 Bridge 与执行业务代码两部分,对应图中上下两部分:

渲染机制

首次渲染时(图中自右向左的流程),JS 线程将视图信息(结构、样式、属性等)传递给 Shadow 线程,建立出用于布局计算的 Shadow Tree,Shadow 线程计算好布局以后,再将完整的视图信息(包括宽高、位置等)传递给主线程,主线程据此建立 Native View

用户交互时(图中自左向右的流程),则先由主线程将相关信息打包成事件消息传递到 Shadow 线程,再根据 Shadow Tree 创建的映射关系生成相应元素的指定事件,最后将事件传递到 JS 线程,执行对应的 JS 回调函数

架构演进

最初的设计也带来了一些限制:

  • 异步:没法将 JavaScript 逻辑直接与许多须要同步答案的 Native API 集成

  • 批处理:很难让 React Native 应用调用 Native 实现的函数

  • 可序列化:存在没必要要的 copy,而不是直接共享内存

这些问题在 Native + React Native 的混合应用中尤为突出,所以,2018 年 6 月提出了大规模的架构升级计划:

具体包含 3 点重大改动:

  • JavaScript 层:引入 JSI,容许替换不一样的 JavaScript 引擎

  • Bridge 层:划分红 Fabric 和 TurboModules 两部分,分别负责 UI 管理与 Native 模块

  • Native 层:精简核心模块,将非核心部分拆分出去做为社区模块独立更新维护

Fabric 指望简化渲染流程中复杂的跨线程交互,容许 JavaScript 直接控制高优先级的 UI 操做,甚至容许同步调用(应对列表快速滚动、页面切换、手势处理等场景)

TurboModules 容许按需加载 Native 模块,并在模块初始化以后直接持有其引用,再也不依靠消息通讯来调用模块功能

P.S.关于 React Native 架构升级的更多信息,见React Native 架构演进

三.生态:Learn once, write anywhere ?

React Native 最初的愿景是learn once, write anywhere

It’s worth noting that we’re not chasing “write once, run anywhere.” Different platforms have different looks, feels, and capabilities, and as such, we should still be developing discrete apps for each platform, but the same set of engineers should be able to build applications for whatever platform they choose, without needing to learn a fundamentally different set of technologies for each. We call this approach “learn once, write anywhere.”

(摘自React Native: Bringing modern web techniques to mobile)

应用生态

平台支持上,目前(2019/9/21),除官方提供的 Android、iOS 支持外,社区还提供了UWP、Tizen、Web、Mac、Apple TV,甚至微信小程序等支持

P.S.更多支持平台,见Out-of-Tree Platforms

企业应用方面,除 Facebook 外,React Native 在腾讯、百度、京东等大规模企业中都有所应用:

  • 腾讯:QQ 空间、腾讯课堂

  • 百度:手机百度

  • 京东:京东 App

工具生态

React Native 发展至今的 4 年里,工具生态也有了必定程度的发展:

  • 新领域:React VR、Viro VR等等

  • 开发工具:Nuclide(官方提供但已再也不维护)、deco-ide、而且Visual Studio Code、Webstorm、Sublime Text、ATOM等主流 IDE 均已支持 React Native

  • 动画:lottie-react-native、react-native-animatable等等

  • UI 组件:NativeBase、React Native Elements等等

  • 调试工具:Chrome developer tools、Reactotron

  • 测试:Detox、Appium

  • 运维:New Relic、BugSnag

P.S.关于 React Native 生态的更多信息,见Exploring React Native Ecosystem – Tools, backend, database and best libraries

比起积淀深厚的 Android、iOS 技术生态,React Native 生态尚处于较低成熟度的阶段,于是面临与 Native 基础设施集成、跨语言栈调试等难题。但不管怎样,Learn once, write anywhere 的愿景在路上,正向咱们赶来

参考资料

  • React Native 简史

  • React Native 架构一览

  • React Native 架构演进

  • React Native at Airbnb

联系ayqy      

若是在文章中发现了什么问题,请查看原文并留下评论,ayqy看到就会回复的(不建议直接回复公众号,看不到的啦)

特别要紧的问题,能够直接微信联系ayqywx      

本文分享自微信公众号 - 前端向后(backward-fe)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。