一.歷史: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 支持外,社區還提供了UWP、Tizen、Web、Mac、Apple TV,甚至微信小程序等支持
P.S.更多支持平台,見Out-of-Tree Platforms
企業應用方面,除 Facebook 外,React Native 在騰訊、百度、京東等大規模企業中都有所應用:
工具生態
React Native 發展至今的 4 年里,工具生態也有了一定程度的發展:
-
開發工具:Nuclide(官方提供但已不再維護)、deco-ide、並且Visual Studio Code、Webstorm、Sublime Text、ATOM等主流 IDE 均已支持 React Native
-
UI 組件:NativeBase、React Native Elements等等
P.S.關於 React Native 生態的更多信息,見Exploring React Native Ecosystem – Tools, backend, database and best libraries
比起積淀深厚的 Android、iOS 技術生態,React Native 生態尚處於較低成熟度的階段,因而面臨與 Native 基礎設施集成、跨語言棧調試等難題。但無論怎樣,Learn once, write anywhere 的願景在路上,正向我們趕來
參考資料