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源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索