ReactNative介绍

ReactNative 发展历史

起源

React Native 想法来源于2013年的 Facebook 内部黑客马拉松(hackathon)
React Native: A year in review

In the beginning: React Native’s roots
In the essence of Facebook’s hacker culture, React Native started as a hackathon project in the summer of 2013. Similar to React, React Native seemed like a boldly unconventional idea. It wasn’t clear this would actually work. How was touch negotiation between JS and native ScrollViews going to work? What about performance, and what about debugging? None of these challenges stopped the engineers from focusing and pushing forward.

React Native: Bringing modern web techniques to mobile

随着React的快速发展,Facebook越发感受到 React 以及 Web 技术的优势,同时Native在““Move fast” 这一块的糟糕表现,所以就引发了将Web先进技术引进Native的开发,

  • 快速开发(Rapid development velocity):刷新浏览器即可生效,不必等待重新编译 App
  • 快速迭代(Rapid iteration cycle):Web 一天两版,产品迭代周期更短
  • 快速反馈(Immediate testing feedback):Web 发布立即触达用户,A/B test 等实验结果立等可取,产品演进更快

为了实现这个目标,FaceBook尝试过三种方案

  1. Using WebViews ,通过Native提供容器,使用Web进行开发。这样能全面利用Web的开发经验并且具备WEB技术的一样可扩展性,但最终渲染性能并不理想,而且因为全部是Web技术开发也没有沉淀很好的Native技术
  2. Porting React to native,把React移植到native实现,15年推出了iOS componentkit 以及在17年推出了Android Litho 。实现了很多React的特性,例如可预测性UI、声明式。但没有实现提升效率的初衷,仍然需要重新编译。另外需要进行双端适配。而且Web React的生态建设也不能直接复用。
  3. Scripting native,通过 JavaScript 调用 Native API。既能拥有 Web 开发的快速迭代能力,还不局限于 Web 技术,同时也没有脱离 JavaScript 生态,似乎是个完美的方案,然而实践并没有那么简单。主要是Native环境和JS环境来回通信,过多的通信承载以及引起的UI线程阻塞都会带来性能损害。 但最终幸运的是React整体的技术模型仍然可以向着正确的方向演进

发展

2015

unveil three new technologies that we’ve been using internally at Facebook for some time: GraphQL, Relay, and React Native.

React Native is a framework for native environments that allows developers to build first-class iOS and Android user interfaces with no browser/WebView involved

2016

2017

  • February 14, 2017:Using Native Driver for Animated,支持Native驱动动画,早期动画实现在JS线程中,这容易因JS线程Block造成动画的跳帧。
  • March 13, 2017:Better List Views in React Native,提供FlatList和SectionList更好的支持列表实现。同时也提到了一些注意事项,譬如非屏幕部分是异步渲染,所以在快速滑动的时候可能会引起白屏。
  • March 13, 2017:Introducing Create React Native App,推出官方脚手架支持App创建
  • August 7, 2017:React Native Performance in Marketplace,介绍 Facebook 在其 React Native 主应用(Marketplace)上的性能优化实践,后续计划优化编译时的性能优化探索,如Prepack,期望大幅削减 React Native core 的初始化耗时
    image

2018

  • January 18, 2018:Implementing Twitter’s App Loading Animation in React Native,Twitter动画的一些实践,并且在动画方面有一些成果,Fade、Scale、Hide
  • March 22, 2018:Building <InputAccessoryView> For React Native,支持 InputAccessoryView组件
  • May 7, 2018:Using TypeScript with React Native,支持TS语言
  • June 14, 2018:State of React Native 2018,介绍团队正在对整体架构进行重构升级,旨在使得框架更加轻量和更加监控,主要聚焦三个方面
    1. 针对高优先级的更新可以在任何线程同步调用JS线程,以及取代每次UI更新需要经历三层线程模型,使得JS线程可以根据。
    2. 合并异步渲染以及简化异步数据处理
    3. 轻量化桥实现,JS和Native之间桥交互性能更高效
  • July 4, 2018:Releasing 0.56,发布 0.56,升级 Babel、Android SDK、Xcode、Flow 等依赖版本
  • November 1, 2018:Open Source Roadmap,计划精简核心模块,并开源 Facebook 内部的一些基建
  • January 7, 2019: The State of the React Native Community in 2018,说明2018计划更好地支持 Native & React Native 混合 App,核心团队启动了架构升级计划(Fabric),包括重构线程模型、支持 React async rendering 能力、简化 React Native core 等大改。

2019

2020

ReactNative 运行原理

系统设计

整体由React、JavaScript、Bridge、Native四层组成,Native负责UI更新及交互处理,JavaScript调用Native能力实现业务功能,Bridge则为两者之间提供通信桥梁

  • 最上层提供类 React 支持,运行在JavaScriptCore提供的 JavaScript 运行时环境中
  • Bridge 层将 JavaScript 与 Native 环境连接起来,JSON用来传递UI更新信息,Shadow Tree 用来定义 UI 效果及交互功能,Native Modules 提供 Native 功能(比如蓝牙),二者之间通过 JSON 消息相互通信
    • 异步(asynchronous):不依赖于同步通信
    • 可序列化(serializable):保证一切 UI 操作都能序列化成 JSON 并转换回来
    • 批处理(batched):对 Native 调用进行排队,批量处理

系统分层

image

系统结构(Android)(引用)

image

线程模型

React Native 中主要有3种线程

  • UI Thread:Android/iOS(或其它平台)应用中的主线程
  • Shadow Thread:进行布局计算和构造 UI 界面的线程
  • JS Thread:React或其它JavaScript 代码都在这个线程执行

此外,还有一类 Native Modules 线程,不同的 Native Module 可以运行在不同的线程中http://chain-react-bridging.surge.sh/dist/96efedea67e784036f946c487a06cdc9.png

线程工作流程

image

[图片上传失败...(image-e9c98f-1588644627850)]

线程交互流程

image

启动流程

  • 启动RN App
  • 加载JavaScript VM、JavaScript Bundle、NativeModule
  • 执行JavaScript bundle
  • native调用、shadow tree创建、布局、NativeView创建
  • View渲染

整体启动流程

image

官方启动时间模块划分

image

渲染流程

事件传递

image

首次渲染

image

更新渲染

image

架构演进

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

以前架构问题:

  • 异步:无法将 JavaScript 逻辑直接与许多需要同步的 Native API 集成
  • 同步桥支持差:在官方代码注释中提到,同步桥存在严重的性能问题,并且会引入线程BUG
  • 通信性能瓶颈:JS与Native通信采用消息队列的方式,传输过程中需要将要传递的消息序列化为JSON。当传输数据量变大时,桥上会出现拥塞

改进方向

React 层

提供 CodeGen 工具来保证消息通信的类型安全,以解决 JavaScript 与 Native 通信中被广为诟病的 Bridge API 数据类型问题

JavaScript 层

上层 JavaScript 代码需要一个运行时环境,在 React Native 中这个环境是 JSC(JavaScriptCore)。不同于之前直接将 JavaScript 代码输入给 JSC,新的架构中引入了一层 JSI(JavaScript Interface),作为 JSC 之上的抽象,用来屏蔽 JavaScript 引擎的差异,允许换用不同的 JavaScript 引擎(如Hermes)

Bridge 层

划分成 Fabric 和 TurboModules 两部分,分别负责 UI 管理与 Native 模块

Fabric 期望以更现代化的方式去实现 React Native 的渲染层,简化之前渲染流程中复杂跨线程交互(React -> Native -> Shadow Tree -> Native UI)。具体的,直接在 C++层创建 JavaScript 与 Native 共享的 Shadow Tree,并通过 JSI 层将 UI 操作接口暴露给 JavaScript,允许 JavaScript 直接控制高优先级的 UI 操作,甚至允许同步调用(应对列表快速滚动、页面切换、手势处理等场景)

TurboModules 之前所有 Native Modules(无论是否需要用到)都要在应用启动时进行初始化,因为 Native 不知道 JavaScript 将会调用哪些功能模块。而新的TurboModules 允许按需加载 Native 模块,并在模块初始化之后直接持有其引用,不再依靠消息通信来调用模块功能。因此,应用的启动时间也会有所提升

Native 层

精简核心模块,将非核心部分拆分出去作为社区模块独立更新维护,理论上 React Native 应该是通用的,对平台无感知,这是能够支持Web、Windows等不同平台的关键
虽然 Native 不在 React Native 的掌控中,无法垂直地深入优化,但可以进行横向的精简,将非核心的部分代码拆分出去作为社区模块,如 AsyncStorage、ImageStore、MaskedViewIOS、NetInfo 等等。一方面缩减包体积,另一方面也有利于这些模块的独立更新维护

[图片上传失败...(image-3798ee-1588644627850)]


参考
CHANGELOG
The New React Native Architecture Explained
React.js Conf 2016 - Tadeu Zagallo - Optimising React Native: Tools and Tips
Bridging in React Native
React Native - Fabric review-2018-07-25
How React Native constructs app layouts (and how Fabric is about to change it)
React Native
ReactNative源码篇

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,189评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,577评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,857评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,703评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,705评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,620评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,995评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,656评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,898评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,639评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,720评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,395评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,982评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,953评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,195评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,907评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,472评论 2 342