跳到主要內容
黯羽輕揚每天積累一點點

1000 千米高空俯瞰 React Native

免費2019-09-21#Tool#dive into React Native#React Native overview#React Native high level perspective#完全理解 React Native#鸟瞰 React Native

從歷史、架構、生態三個層面審視 React Native 技術

一.歷史:React Native 從開始到現在

React Native 的定位是通過 React 構建原生 App:

A framework for building native apps with React.

具有 5 大特性:

  • Create native apps for Android and iOS using React:用 React 創建 Android、iOS 應用

  • Written in JavaScript—rendered with native code:寫的是 JavaScript,實際渲染的是 Native 界面

  • Native Development For Everyone:基於平台無關的基礎組件開發,就能獲得平台原生體驗

  • Seamless Cross-Platform:無縫過渡,Native 代碼能夠包裝成 React Native 可用的組件

  • Fast Refresh:改動立即生效,擁有 Web 一樣的開發速度

那麼,有 2 個問題:

  • 為什麼要用 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 支持外,社區還提供了 UWPTizenWebMacApple TV,甚至 微信小程序 等支持。

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

企業應用方面,除 Facebook 外,React Native 在騰訊、百度、京東等大規模企業中都有所應用:

工具生態

React Native 發展至今的 4 年裡,工具生態也有了一定程度的發展:

P.S.關於 React Native 生態的更多信息,見 Exploring React Native Ecosystem – Tools, backend, database and best libraries

比起積澱深厚的 Android、iOS 技術生態,React Native 生態尚處於較低成熟度的階段,因而面臨與 Native 基礎設施集成、跨語言棧調試等難題。但無論怎樣,Learn once, write anywhere 的願景在路上,正向我們趕來

參考資料

評論

暫無評論,快來發表你的看法吧

提交評論