React Native 架構演進


寫在前面

上一篇(React Native 架構一覽)從設計、線程模型等方面介紹了 React Native 的現有架構,本篇將分析這種架構的局限性,以及 React Native 正在進行的架構升級計划

 

一.現有架構的局限性

最初的設計也帶來了一些限制:

  • 異步:無法將 JavaScript 邏輯直接與許多需要同步答案的 Native API 集成

  • 批處理:很難讓 React Native 應用調用 Native 實現的函數

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

這些問題在 Native + React Native 的混合應用中尤其突出:

For apps that are entirely built in React Native, these restrictions are usually bearable. But for apps with complex integration between React Native and existing app code, they are frustrating.

 

二.架構升級計划

因此,2018 年 6 月提出大規模重構的計划,目的是更好地支持混合應用:

We're working on a large-scale rearchitecture of React Native to make the framework more flexible and integrate better with native infrastructure in hybrid JavaScript/native apps.

 

 

具體的,有 3 點重大改動:

  • 線程模型:允許在任意線程中同步調用 JavaScript執行高優先級的更新,UI 更新不再非要跨 3 個線程才能進行

  • React:支持 React 16+的新特性,包括async rendering、Data Fetching 等等

  • Bridge:精簡優化,允許 Native 與 JavaScript 之間的直接調用

支持同步調用讓之前很難實現的一些東西成為了可能,例如跨語言的調用棧追蹤

對應到架構圖中,相當於對每一層進行單獨優化:

  • React 層:增強 JavaScript 類型安全,並支持 React 16+新特性

  • JavaScript 層:引入 JSI,允許替換不同的 JavaScript 引擎

  • Bridge 層:划分成 Fabric 和 TurboModules 兩部分,分別負責 UI 渲染與 Native 模塊

  • Native 層:精簡核心模塊,將非核心部分拆分出去作為社區模塊獨立更新維護

初步估計,這些重構工作預期在 2019 年底或 2020 年初完成:

It’s likely this massive piece of work will reach its conclusion around Q4 2019 or Q1 2020, but there are no confirmed dates.

P.S.目前(2019/9/8)除已完成的 JSI 外,其余重構計划仍在進行中,具體見The New React Native Architecture Explained: Part Four

 

三.增強 JavaScript 類型安全

 

 

主要變化在於,提供 CodeGen 工具來保證消息通信的類型安全,以解決 JavaScript 與 Native 通信中被廣為詬病的 Bridge API 數據類型問題:

We also experienced many issues in which the types coming from JavaScript were unexpected. For example, integers were often wrapped by strings, an issue that isn’t realized until it is passed over a bridge. To make matters worse, sometimes iOS will fail silently while Android will crash.

(摘自React Native at Airbnb: The Technology

另一方面,類型約束對通信性能也有一定幫助:

This automation will speed up the communication too, as it’s not necessary to validate the data every time.

 

四.引入 JSI

 

 

上層 JavaScript 代碼需要一個運行時環境,在 React Native 中這個環境是 JSC(JavaScriptCore)。不同於之前直接將 JavaScript 代碼輸入給 JSC,新的架構中引入了一層 JSI(JavaScript Interface),作為 JSC 之上的抽象,用來屏蔽 JavaScript 引擎的差異,允許換用不同的 JavaScript 引擎(如最近推出的Hermes

更重要的,有了 JSI 之后,JavaScript 還能持有 C++對象的引用,並調用其方法:

By using JSI, JavaScript can hold reference to C++ Host Objects and invoke methods on them.

從而允許 JavaScript 與 Native 的直接調用,而不必通過跨線程消息通信,省去序列化/反序列化的成本,還能減輕 Bridge 的通信壓力(如大量消息排隊堵車)

同時JSI 所在的 C++層也可以作為復用 Native 代碼的一種方式,擁有 Native 的天然支持:

  • Android:通過 JNI(Java Native Interface)調用 C 或 C++模塊

  • iOS:Objective-C 默認支持

 

五.重構 Bridge 層

 

 

新的 Bridge 層被划分成 Fabric 和 TurboModules 兩部分:

  • Fabric:負責管理 UI

  • TurboModules:負責與 Native 交互

Fabric 期望以更現代化的方式去實現 React Native 的渲染層,簡化之前渲染流程中復雜跨線程交互(React -> Native -> Shadow Tree -> Native UI)。具體的,直接在 C++層創建 JavaScript 與 Native 共享的 Shadow Tree,並通過 JSI 層將 UI 操作接口暴露給 JavaScript,允許 JavaScript 直接控制高優先級的 UI 操作,甚至允許同步調用(應對列表快速滾動、頁面切換、手勢處理等場景)

之前所有 Native Modules(無論是否需要用到)都要在應用啟動時進行初始化,因為 Native 不知道 JavaScript 將會調用哪些功能模塊。而新的TurboModules 允許按需加載 Native 模塊,並在模塊初始化之后直接持有其引用,不再依靠消息通信來調用模塊功能。因此,應用的啟動時間也會有所提升

 

六.精簡核心模塊

 

 

理論上,React Native 應該是通用的,對平台無感知,這是能夠支持WebWindows等不同平台的關鍵

雖然 Native 不在 React Native 的掌控中,無法垂直地深入優化,但可以進行橫向的精簡,將非核心的部分代碼拆分出去作為社區模塊,如 AsyncStorage、ImageStore、MaskedViewIOS、NetInfo 等等。一方面縮減包體積,另一方面也有利於這些模塊的獨立更新維護

 

參考資料


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM