UTALI

みんなの役に立つ情報をどんどん公開していきます

React Nativeの利用例 | 【翻訳】 InstagramではReact Nativeをどのように利用しているのか?

React Nativeは2015年にオープンソース化してから長い時間が経ちました。2年前にはFacebookとFacebook Ads Managerにしか利用されていませんでしたが、現在ではフォーチューン500企業を含む多くのスタートアップに利用されています。

開発速度はインスタグラムのモバイル開発の価値を決定します。2016年の初頭に私たちはコードの共有化と迅速な開発を通した機能更新の高速化を視野に、React Nativeの採用を検討するようになりました。React Nativeの特徴であるライブリロードやホットリロードなどの機能によって、コンパイルやインストールにかかる時間の削減を目指したのです。

難しかったところ

React Nativeを既存のアプリと統合することは、ネイティヴで開発する場合とは異なった難しさと余計な手間を必要とします。この観点から、最初に自分たちが考えられる最も簡単なケースであるビューを実装することにしました。 - プッシュ通知のビューです。

このビューは当初はWebViewによって実装されていましたので、最初に始めるものとしては、それほど困難ではないと考えたのです。

何よりも、このビューはナビゲーションのインフラを構築する手間があまりかからなかったというのがあります。このUIは非常にシンプルで、翻訳もサーバーサイドで可能だったのです。

Androidのメソッド数の問題

最初に直面した問題はライブラリ全体をプルすることなくReact Nativeを依存対象として追加することが困難だったということです。

そうするとバイナリのサイズが増えてしまうだけでなく、Android版でのメソッド数の制限に引っかかってしまうのです。マルチデックス構造にすることも可能ですが、インスタグラムではパフォーマンスを重要視しているため、シングルデックス構造から脱却することは考えられません。

最終的な実装では、ビューマネージャーに対してのみ必要なメソッドを追加することになった。そして利用したくないものに対しては、Instagramの開発チームが同等の機能を持った実装を行なった。

最終的に3500のメソッドにまで削ることができた。React Nativeで機能を追加するには、わずかにJavaを書く必要があったが、これも将来の投資として役立つだろうと考えた。

メトリックス

プッシュ通知設定の実験として、React Nativeのクラッシュやメモリ不足などのいくつかのメトリックスにおける影響を検証した。

結果から言えば、これらのメトリクスにおいては、初期の実験においても、ユーザーがReact Native実装の箇所を離脱した場合でのブリッジ・インスタンスを保持した場合においても、中立だった。これは次に同じ箇所に流入した場合でも別のインスタンスが確保されることなく、再利用されるということを意味していた。

起動時のパフォーマンス

React Nativeはアプリの起動時にJavaScriptのバンドルを仮想マシンに注入して、ネイティブモジュールとビューマネージャーを初期化するために、一定のオーバーヘッドが生じる。

しかし、React Nativeのチームは長い時間をかけてパフォーマンスの改善を試みた。React Nativeによるコードの共通化によるトレードオフが納得できる水準になるかを測定した。

その検証のために、ネイティヴで実装されていた「プロフィールの編集」画面をReact Nativeに移行することにした。この検証の過程で、制作チーム(ナビゲーション、翻訳、コアコンポーネント)が平行に利用できる製品インフラを構築しました。

製品

前の章で述べた通りで、コアクライアントチームは、プッシュ通知設定とプロフィール設定のビューをReact Nativeに移行した。そしてInstagramの開発チームは、次に写真のギャラリー画面を、React Nativeのリスト機能のパフォーマンスの測定のために、移行することにした。

これらの例に加えて、複数のプロダクトチームはReact Nativeに機能を追加することにした。

f:id:mochizuki_p:20170516114941p:plain

プロモーション投稿

Instagramでは「プロモーション投稿」という軽量インターフェイスを実装している。この機能は、ネィティブコードよりも高速に実装できるという理由でWebViewを利用していた。問題はWebViewはUXがネィティブと異なることとページのロードとレンダリングにかかる時間です。

この機能を担当するチームはこの機能をReact Nativeに移行して、起動時間とUXを大幅に改善しました。特に非常に複雑な生成フローにも関わらず、たった6つのメソッドをAndroidの層に追加しただけで済んだことは、特筆に値します。

保存機能

6億人のユーザーが毎月Instagramを利用して、彼らのコミュニティと繋がりながら好奇心をベースにした価値観を発見していきます。

しかし、ユーザーはいつでも新しい体験を求めているわけではありません。以前見たコンテンツに再訪することもよくあることです。彼らのニーズに応えるために、保存機能を担当するチームは、保存機能を実装して、ユーザーにプライベートタブを経由して、保存した画像の一覧を見られるようにしました。

このチームはiOSでの機能をReact Nativeで実装しました。

チェックポイント

スパムが疑われる時などは、ユーザーに電話番号などを訪ねることがあります。これがチェックポイントです。

かつてはチェックポイントはWebViewsを利用して実装されていました。以前述べたように、これは開発スピードとコードの共有化には有利ですが、UXには悪影響で起動も遅いという欠点があります。

保護機能を担当するチームはこれらの欠点の改修のために一仕事をすることにしました。React Nativeを起動時間の遅さとUXの改善を図りながらコードを共有するために活用することにしたのです。

コメント制限

我々開発チームはInstagramが誰にとっても安全で大事なひと時を共有するのにふさわしい場所であればと願っています。Instagramのコミュニティが大きくなり、投稿されるコンテンツの量が増えるにつれて、安全でポジティブな空間を守るための努力も増えていきました。特に気を使っているのが写真やビデオについたコメントです。 この機能を担当するチームはユーザーが投稿されるコメントを制限できる機能をReact Nativeで追加することにしました。

Lead Gen 広告

Lead Gen 広告はユーザーに広告主との情報共有を可能にする機能です。広告主はこのフォームを自由にカスタマイズすることができます。

まとめ

React Nativeは開発チームにiOS、Android両方に機能を高速で追加することを可能にしました。 以下のリストは各機能でコードを共通化できた割合です。

  • プロモーション投稿 99%
  • SMS Captcha 97%
  • コメント制限 85%
  • Lead Gen 広告 87%
  • プッシュ通知設定 92%

engineering.instagram.com