ReactNative 發(fā)展歷史
起源
React Native 想法來源于2013年的 Facebook 內(nèi)部黑客馬拉松(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的快速發(fā)展瞭亮,F(xiàn)acebook越發(fā)感受到 React 以及 Web 技術的優(yōu)勢礼烈,同時Native在““Move fast” 這一塊的糟糕表現(xiàn)科吭,所以就引發(fā)了將Web先進技術引進Native的開發(fā),
- 快速開發(fā)(Rapid development velocity):刷新瀏覽器即可生效,不必等待重新編譯 App
- 快速迭代(Rapid iteration cycle):Web 一天兩版豺憔,產(chǎn)品迭代周期更短
- 快速反饋(Immediate testing feedback):Web 發(fā)布立即觸達用戶爵政,A/B test 等實驗結果立等可取碴裙,產(chǎn)品演進更快
為了實現(xiàn)這個目標钢悲,F(xiàn)aceBook嘗試過三種方案
- Using WebViews 点额,通過Native提供容器舔株,使用Web進行開發(fā)。這樣能全面利用Web的開發(fā)經(jīng)驗并且具備WEB技術的一樣可擴展性还棱,但最終渲染性能并不理想载慈,而且因為全部是Web技術開發(fā)也沒有沉淀很好的Native技術
- Porting React to native,把React移植到native實現(xiàn)珍手,15年推出了iOS componentkit 以及在17年推出了Android Litho 办铡。實現(xiàn)了很多React的特性,例如可預測性UI琳要、聲明式寡具。但沒有實現(xiàn)提升效率的初衷,仍然需要重新編譯稚补。另外需要進行雙端適配童叠。而且Web React的生態(tài)建設也不能直接復用。
- Scripting native课幕,通過 JavaScript 調(diào)用 Native API厦坛。既能擁有 Web 開發(fā)的快速迭代能力五垮,還不局限于 Web 技術,同時也沒有脫離 JavaScript 生態(tài)杜秸,似乎是個完美的方案放仗,然而實踐并沒有那么簡單。主要是Native環(huán)境和JS環(huán)境來回通信撬碟,過多的通信承載以及引起的UI線程阻塞都會帶來性能損害诞挨。 但最終幸運的是React整體的技術模型仍然可以向著正確的方向演進
發(fā)展
2015
- February 18, 2015 : React.js Conf Round-up 2015,首次揭幕FaceBook內(nèi)部使用技術ReactNative
unveil three new technologies that we’ve been using internally at Facebook for some time: GraphQL, Relay, and React Native.
- March 26, 2015: F8 2015: New Open Source Tools for Mobile Developers呢蛤,首次發(fā)布并開源ReactNative
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
- MAR 26, 2015: React Native: Bringing modern web techniques to mobile亭姥,發(fā)布第一篇官方介紹,此時僅支持 iOS
- SEP 14, 2015:React Native for Android: How we built the first cross-platform React Native app顾稀,宣布 React Native 支持 Android 了达罗,文章中提到兩個大的認知,1是iOS和Android獨立開發(fā)并不可取静秆,最終兩端基于一個公共庫進行開發(fā)粮揉;2是初始階段由于雙端未充分的測試帶來的成本要高于開發(fā)成本,不過這些偶發(fā)的問題在不斷的技術抹平差異后帶來了穩(wěn)定性的提高
2016
- March 24, 2016:Introducing Hot Reloading抚笔,熱加載介紹扶认,實現(xiàn)了變更實施可見
- MAR 28, 2016:Dive into React Native performance,全面提升性能
- Cleanup Require/Babel helpers (high impact): 清楚無用引用
- Avoid copying and decoding strings when loading the bundle (medium impact): 加載bundle避免復制和解碼
- Stripping DEV-only modules (low impact): 支持Dev模塊殊橙,減少體積從而提升JS轉換效率
- Generate event descriptions on the server (low impact): Data后移辐宾,減少客戶端處理數(shù)據(jù)操作
- Lazy requires (low impact): 按需加載模塊
- Relay incremental cache read (high impact): 提神緩存讀取效率
- De-batching bridge calls, batch Relay calls (high impact): 批處理橋交互操作
- Early UI flushing (low impact): UI刷新批處理
- Lazy native modules loading (low impact): 懶加載Native模塊
- Lazy touch bindings on text components (low impact): 懶加載組件
- Defer popular events query (medium impact): 延期處理屏幕事件
- APRIL 13, 2016 :React Native on the Universal Windows Platform,Windows平臺實現(xiàn)
- APR 142016:Samsung Committed to Bringing React Native to Tizen:進入三星物聯(lián)網(wǎng)生態(tài)(Tizen 系統(tǒng))進入三星物聯(lián)網(wǎng)生態(tài)(Tizen 系統(tǒng))
- August 19, 2016:Making an App RTL-ready膨蛮,支持RTL布局
- October 25, 2016:0.36: Headless JS, the Keyboard API, & more叠纹,發(fā)布0.36版本,Headless支持后臺任務敞葛、鍵盤操作等
- November 8, 2016:Introducing Button, Faster Installs with Yarn, and a Public Roadmap誉察,發(fā)布0.37版本,支持Button組件惹谐,支持Yarn
2017
- February 14, 2017:Using Native Driver for Animated持偏,支持Native驅(qū)動動畫,早期動畫實現(xiàn)在JS線程中氨肌,這容易因JS線程Block造成動畫的跳幀鸿秆。
- March 13, 2017:Better List Views in React Native,提供FlatList和SectionList更好的支持列表實現(xiàn)怎囚。同時也提到了一些注意事項卿叽,譬如非屏幕部分是異步渲染,所以在快速滑動的時候可能會引起白屏。
- March 13, 2017:Introducing Create React Native App附帽,推出官方腳手架支持App創(chuàng)建
- August 7, 2017:React Native Performance in Marketplace埠戳,介紹 Facebook 在其 React Native 主應用(Marketplace)上的性能優(yōu)化實踐,后續(xù)計劃優(yōu)化編譯時的性能優(yōu)化探索蕉扮,如Prepack整胃,期望大幅削減 React Native core 的初始化耗時
2018
- January 18, 2018:Implementing Twitter’s App Loading Animation in React Native,Twitter動畫的一些實踐喳钟,并且在動畫方面有一些成果屁使,F(xiàn)ade、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易茬,介紹團隊正在對整體架構進行重構升級酬蹋,旨在使得框架更加輕量和更加監(jiān)控,主要聚焦三個方面
- 針對高優(yōu)先級的更新可以在任何線程同步調(diào)用JS線程抽莱,以及取代每次UI更新需要經(jīng)歷三層線程模型范抓,使得JS線程可以根據(jù)。
- 合并異步渲染以及簡化異步數(shù)據(jù)處理
- 輕量化橋?qū)崿F(xiàn)食铐,JS和Native之間橋交互性能更高效
- July 4, 2018:Releasing 0.56匕垫,發(fā)布 0.56,升級 Babel虐呻、Android SDK象泵、Xcode、Flow 等依賴版本
- November 1, 2018:Open Source Roadmap斟叼,計劃精簡核心模塊偶惠,并開源 Facebook 內(nèi)部的一些基建
- 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
-
March 12, 2019:Releasing React Native 0.59绢淀,發(fā)布0.59
- Hooks支持
- JSC更新萤悴,和性能提升,以及Android 64位支持
- inline requires支持皆的,更快app啟動性能
- Lean core is underway覆履,核心模塊精簡計劃持續(xù)進行
- CLI improvements
March 31, 2019:Mobile Innovation with React Native, ComponentKit, and Litho,分享 Facebook 的移動技術棧(React Native + ComponentKit 和 Litho)
July 17, 2019:Meet Hermes, a new JavaScript Engine optimized for React Native Hermes 引擎發(fā)布,Hermes: An open source JavaScript engine optimized for mobile apps, starting with React Native
July 3, 2019:Announcing React Native 0.60硝全,0.60發(fā)布栖雾,聚焦一些輔助功能提升,AndroidX支持伟众、Native模塊自動鏈接析藕、Helper更新等
September 18, 2019:Announcing React Native 0.61 with Fast Refresh,新概念“Fast Flush”凳厢,更可靠和更高效的本地更新渲染能力
2020
- March 26, 2020:Announcing React Native 0.62 with Flipper账胧,發(fā)布0.62,提供Flipper先紫,更友好的支持Debug調(diào)試
ReactNative 運行原理
系統(tǒng)設計
整體由React治泥、JavaScript、Bridge遮精、Native四層組成居夹,Native負責UI更新及交互處理,JavaScript調(diào)用Native能力實現(xiàn)業(yè)務功能本冲,Bridge則為兩者之間提供通信橋梁
- 最上層提供類 React 支持吮播,運行在JavaScriptCore提供的 JavaScript 運行時環(huán)境中
- Bridge 層將 JavaScript 與 Native 環(huán)境連接起來,JSON用來傳遞UI更新信息眼俊,Shadow Tree 用來定義 UI 效果及交互功能意狠,Native Modules 提供 Native 功能(比如藍牙),二者之間通過 JSON 消息相互通信
- 異步(asynchronous):不依賴于同步通信
- 可序列化(serializable):保證一切 UI 操作都能序列化成 JSON 并轉換回來
- 批處理(batched):對 Native 調(diào)用進行排隊疮胖,批量處理
系統(tǒng)分層
系統(tǒng)結構(Android)(引用)
線程模型
React Native 中主要有3種線程
- UI Thread:Android/iOS(或其它平臺)應用中的主線程
- Shadow Thread:進行布局計算和構造 UI 界面的線程
- JS Thread:React或其它JavaScript 代碼都在這個線程執(zhí)行
此外环戈,還有一類 Native Modules 線程,不同的 Native Module 可以運行在不同的線程中http://chain-react-bridging.surge.sh/dist/96efedea67e784036f946c487a06cdc9.png
線程工作流程
[圖片上傳失敗...(image-e9c98f-1588644627850)]
線程交互流程
啟動流程
- 啟動RN App
- 加載JavaScript VM澎灸、JavaScript Bundle院塞、NativeModule
- 執(zhí)行JavaScript bundle
- native調(diào)用、shadow tree創(chuàng)建性昭、布局拦止、NativeView創(chuàng)建
- View渲染
整體啟動流程
官方啟動時間模塊劃分
渲染流程
事件傳遞
首次渲染
更新渲染
架構演進
2018 年 6 月啟動了架構升級計劃 Fabric,重構線程模型并簡化 React Native Core糜颠,以更好地支持 Native & React Native 混合 App
以前架構問題:
- 異步:無法將 JavaScript 邏輯直接與許多需要同步的 Native API 集成
- 同步橋支持差:在官方代碼注釋中提到汹族,同步橋存在嚴重的性能問題,并且會引入線程BUG
- 通信性能瓶頸:JS與Native通信采用消息隊列的方式其兴,傳輸過程中需要將要傳遞的消息序列化為JSON顶瞒。當傳輸數(shù)據(jù)量變大時,橋上會出現(xiàn)擁塞
改進方向
React 層
提供 CodeGen 工具來保證消息通信的類型安全元旬,以解決 JavaScript 與 Native 通信中被廣為詬病的 Bridge API 數(shù)據(jù)類型問題
JavaScript 層
上層 JavaScript 代碼需要一個運行時環(huán)境榴徐,在 React Native 中這個環(huán)境是 JSC(JavaScriptCore)守问。不同于之前直接將 JavaScript 代碼輸入給 JSC,新的架構中引入了一層 JSI(JavaScript Interface)坑资,作為 JSC 之上的抽象耗帕,用來屏蔽 JavaScript 引擎的差異,允許換用不同的 JavaScript 引擎(如Hermes)
Bridge 層
劃分成 Fabric 和 TurboModules 兩部分袱贮,分別負責 UI 管理與 Native 模塊
Fabric 期望以更現(xiàn)代化的方式去實現(xiàn) React Native 的渲染層仿便,簡化之前渲染流程中復雜跨線程交互(React -> Native -> Shadow Tree -> Native UI)。具體的字柠,直接在 C++層創(chuàng)建 JavaScript 與 Native 共享的 Shadow Tree探越,并通過 JSI 層將 UI 操作接口暴露給 JavaScript,允許 JavaScript 直接控制高優(yōu)先級的 UI 操作窑业,甚至允許同步調(diào)用(應對列表快速滾動钦幔、頁面切換、手勢處理等場景)
TurboModules 之前所有 Native Modules(無論是否需要用到)都要在應用啟動時進行初始化常柄,因為 Native 不知道 JavaScript 將會調(diào)用哪些功能模塊鲤氢。而新的TurboModules 允許按需加載 Native 模塊,并在模塊初始化之后直接持有其引用西潘,不再依靠消息通信來調(diào)用模塊功能卷玉。因此,應用的啟動時間也會有所提升
Native 層
精簡核心模塊喷市,將非核心部分拆分出去作為社區(qū)模塊獨立更新維護相种,理論上 React Native 應該是通用的,對平臺無感知品姓,這是能夠支持Web寝并、Windows等不同平臺的關鍵
雖然 Native 不在 React Native 的掌控中,無法垂直地深入優(yōu)化腹备,但可以進行橫向的精簡衬潦,將非核心的部分代碼拆分出去作為社區(qū)模塊,如 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源碼篇