メインコンテンツへスキップ

React Nativeの現状 2018

·5分で読めます
Sophie Alpert
Facebook React エンジニアリングマネージャー

React Nativeの現状について最後のアップデートを公開してから、しばらく時間が経ちました。

Facebookでは、これまで以上に多くの重要なプロジェクトでReact Nativeを使用しています。最も人気のある製品の1つはMarketplaceで、これはFacebookアプリのトップレベルタブの1つであり、毎月8億人の人々に利用されています。2015年の創設以来、MarketplaceのすべてはReact Nativeで構築されており、アプリのさまざまな部分にわたる100以上の全画面ビューも含まれています。

また、アプリの多くの新しい部分にもReact Nativeを使用しています。先月のF8キーノートをご覧になった方は、「献血」、「クライシスレスポンス」、「プライバシーショートカット」、「安否確認」といった機能をご存知でしょう。これらはすべてReact Nativeで構築された最近の機能です。また、Facebookのメインアプリ以外のプロジェクトでもReact Nativeが使われています。新しいOculus Go VRヘッドセットには、コンパニオンモバイルアプリが付属していますが、これは完全にReact Nativeで構築されています。言うまでもなく、ヘッドセット自体の多くの体験はReact VRによって支えられています。

もちろん、私たちはアプリを構築するために他の多くの技術も使用しています。LithoComponentKitは、アプリで広範に使用している2つのライブラリで、どちらもネイティブスクリーンを構築するためのReactのようなコンポーネントAPIを提供します。React Nativeが他のすべての技術を置き換えることが目標であったことは一度もありません。私たちはReact Native自体をより良くすることに焦点を当てていますが、他のチームがReact Nativeからアイデアを借用しているのを見るのも喜ばしいことです。例えば、JavaScript以外のコードにもインスタントリロードをもたらすといった例です。

アーキテクチャ

2013年にReact Nativeプロジェクトを開始したとき、私たちはJavaScriptとネイティブの間に、非同期で、シリアライズ可能で、バッチ処理される単一の「ブリッジ」を持つように設計しました。React DOMがReactの状態更新をdocument.createElement(attrs).appendChild()のような命令的でミュータブルなDOM API呼び出しに変換するのと同じように、React Nativeは[["createView", attrs], ["manageChildren", ...]]のような実行すべき変更のリストを含む単一のJSONメッセージを返すように設計されました。私たちはシステム全体を、同期的な応答をあてにせず、そのリストのすべてがJSONに完全にシリアライズ・デシリアライズできることを保証するように設計しました。これにより、私たちは柔軟性を得ることができました。このアーキテクチャの上に、すべてのJavaScriptコードをWebSocket接続を介して非同期に実行するChromeデバッグのようなツールを構築することができました。

過去5年間で、これらの初期の原則が一部の機能の構築を困難にしていることがわかりました。非同期ブリッジは、同期的な応答を期待する多くのネイティブAPIとJavaScriptロジックを直接統合できないことを意味します。ネイティブ呼び出しをキューに入れるバッチ処理ブリッジは、React Nativeアプリがネイティブで実装された関数を呼び出すことを難しくします。そして、シリアライズ可能なブリッジは、2つの世界間でメモリを直接共有する代わりに、不必要なコピーを意味します。完全にReact Nativeで構築されたアプリにとって、これらの制限は通常耐えられます。しかし、React Nativeと既存のアプリコードとの間に複雑な統合があるアプリにとっては、これらは不満の原因となります。

私たちは、React Nativeのフレームワークをより柔軟にし、ハイブリッドなJavaScript/ネイティブアプリのネイティブインフラストラクチャとより良く統合するために、大規模な再設計に取り組んでいます。このプロジェクトでは、過去5年間で学んだことを応用し、アーキテクチャを段階的によりモダンなものにしていきます。React Nativeの内部の多くを書き直していますが、変更のほとんどは水面下で行われます。既存のReact Nativeアプリは、ほとんどまたは全く変更なしで動作し続けます。

React Nativeをより軽量にし、既存のネイティブアプリにより良く適合させるために、この再設計には3つの主要な内部変更があります。第一に、スレッドモデルを変更しています。UIの更新ごとに3つの異なるスレッドで作業を行う必要がある代わりに、任意の優先度の高い更新に対して任意の-スレッドでJavaScriptを同期的に呼び出すことが可能になります。一方で、応答性を維持するために優先度の低い作業はメインスレッドから外します。第二に、複数のレンダリング優先度を可能にし、非同期データ処理を簡素化するために、非同期レンダリング機能をReact Nativeに組み込んでいます。最後に、ブリッジを簡素化してより高速かつ軽量にします。ネイティブとJavaScript間の直接呼び出しはより効率的になり、言語をまたいだスタックトレースのようなデバッグツールの構築が容易になります。

これらの変更が完了すれば、より緊密な統合が可能になります。現在、ネイティブのナビゲーションやジェスチャーハンドリング、あるいはUICollectionViewやRecyclerViewのようなネイティブコンポーネントを複雑なハックなしに組み込むことはできません。スレッドモデルの変更後、このような機能の構築は簡単になるでしょう。

この作業が完了に近づくにつれて、今年後半に詳細を公開する予定です。

コミュニティ

Facebook内のコミュニティと並行して、Facebook外にもReact Nativeのユーザーや協力者の活気あるコミュニティがあることを嬉しく思います。私たちは、React Nativeユーザーへのより良いサービス提供と、プロジェクトへの貢献を容易にすることの両方で、React Nativeコミュニティをさらにサポートしていきたいと考えています。

アーキテクチャの変更がReact Nativeと他のネイティブインフラストラクチャとのよりクリーンな相互運用を助けるのと同様に、React NativeはJavaScript側でもスリムになり、JavaScriptエコシステムにより良く適合する必要があります。これには、VMやバンドラを交換可能にすることが含まれます。私たちは、破壊的変更のペースについていくのが難しいことを理解しているので、メジャーリリースの回数を減らす方法を見つけたいと考えています。最後に、一部のチームが起動時間の最適化といったトピックでより詳細なドキュメントを求めていることも承知しています。この分野では、私たちの専門知識がまだ文書化されていません。今後1年でこれらの変更のいくつかが見られることを期待してください。

あなたがReact Nativeを使用しているなら、あなたは私たちのコミュニティの一員です。React Nativeをあなたにとってより良くするために、引き続きご意見をお聞かせください。

React Nativeはモバイル開発者の道具箱の中の一つのツールに過ぎませんが、私たちが強く信じているツールであり、過去1年間で500人以上のコントリビューターから2500以上のコミットを得て、日々改善しています。