メインコンテンツへ移動

1000 キロメートル高空から React Native を俯瞰

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

歴史、アーキテクチャ、エコシステムの 3 つのレベルから 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 できるようにすることを希望することです

2 番目の質問については、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 層

重要な点は:中間は何なのか?上下 2 つの世界はどのように聯繫しているのか?

アーキテクチャ設計

React Native では、中間は Bridge 層で、メッセージ通信を通じて JavaScript 世界と Native 世界を聯繫します

具体的には、Shadow Tree は UI 効果とインタラクション機能を定義し、Native Modules は Native 機能(例えば Bluetooth)を提供し、二者は 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 の初期化とビジネスコードの実行の 2 部分に分かれ、図の上下 2 部分に対応:

レンダリングメカニズム

初回レンダリング時(図中右から左へのフロー)、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 の 2 部分に分割し、それぞれ 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 のビジョンは路上にあり、私たちに駆け寄ってきています

参考資料

コメント

コメントはまだありません

コメントを書く