DiscordにおけるReact Native導入への道のり
Discord のエンジニアリングディレクターである Chas Jhin をゲストに迎えた React Native Radio ポッドキャストのエピソードの抜粋です
1. Discordの技術的背景とReact Nativeの導入
- 初期の経緯とReactの採用: Discordの初期バージョンはチャットアプリではなく、モバイルMOBAゲーム(Fates Forever)を開発するモバイルゲームスタジオから始まりました。しかし、プレイヤーが利用していたゲーム内チャットとギルド連携機能が好評だったため、チャットアプリへとピボットしました。
- 最初のチャットアプリはReactで構築されたWebアプリでした。これはReactがまだ一般的ではなかった2014年、15年頃の初期の採用でした。
- React Nativeの早期採用: ユーザーがデスク以外でもチャットを続けるためのモバイルアプリが必要になった際、CTOがReact NativeのiOS版がMetaからリリースされて数ヶ月後の早期の段階で、週末を使ってWebアプリをReact Nativeに移植したプロトタイプを構築し、それが機能しました。
- この初期の決定により、Discordは「React Webアプリ」「iOS向けReact Nativeアプリ」、そして「当時の標準的なJava Androidアプリ」という構成でスタートしました。
- Discordは、Web、デスクトップ(ElectronシェルのReactアプリ)、モバイル(Android/iOS向けReact Native)全体でクロスプラットフォームのフレームワークとライブラリを活用しています。
2. Androidへの移行における長年の課題
- Androidへの長期的な移行期間: iOSでは早期にReact Nativeが採用されましたが、AndroidアプリをReact Nativeに完全に移植するには約6年間かかりました。移植の試みは2015年から2021年まで約6ヶ月ごとに行われていましたが、成功しませんでした。
- 初期の障害: 初期段階のReact Native Androidには、特定のスクロール操作やエッジ・トゥ・エッジ検出など、機能的な不足がありました。これらのギャップは、後にReact Navigation、React Native Screens、Reanimatedなどのオープンソースのサードパーティライブラリによって埋められました。
- パフォーマンスの壁: 最大の障害はパフォーマンスでした。特にメッセージを高速にスクロールする際のパフォーマンスが課題でした。コールドスタート時間が30秒、クラッシュ率が5%(Google Playの許容範囲より4%高い)といった問題が発生し、実用に耐えませんでした。
- 移行の鍵(Hermes): Androidへの完全移行を可能にした決定的な要因は、Hermesが十分に安定し、Androidで完全に利用できるようになったことでした(2020年から2021年頃)。
3. React Nativeの強みとNativeコードの戦略的利用
- 生産性の向上(ビジネス上のROI): React Nativeのおかげで、プロダクトエンジニアリングチームは以前よりも格段に迅速にイテレーションできるようになりました。ビジネスの観点から見ると、50人のiOSエンジニアと50人のAndroidエンジニア、計100人が必要だった作業を、30〜40人のReact Nativeエンジニアで実現でき、リリースを待つ時間が減るため、ビジネス上の投資対効果(ROI)が非常に高いです。
- Nativeコードの活用(スーパーパワー): Discordは、特にパフォーマンスが求められる重要な部分ではNativeコードを利用しています。ユーザーにとって最も重要な画面であるコアなチャット機能自体は、特にスムーズなスクロールとリッチメディアの処理のためにNativeコードで実装されています。
- Nativeコードを活用することは、React Nativeの欠陥ではなく、むしろスーパーパワーであり、開発者が恐れるべきではないと強調されています。
アーキテクチャとしてのReact Native: React Nativeは、さまざまなレンダラーやアプローチをオーケストレーションするレイヤーとして設計されています。
4. 新しいアーキテクチャ(New Architecture/Newark)への移行
- 移行の難しさ: 新しいアーキテクチャ(Newark)への移行は、Androidへの移行と同様に非常に困難でした。
- 移行の進捗: 2022年10月から取り組みが始まり、ポッドキャスト収録時点ではAndroid版のNewarkを100%展開しようとしている最中でした。
- 初期と長期の課題: Newarkフラグをオンにして動作するビルドを作成する初期段階は比較的簡単でしたが、残された細かい問題への対応が困難でした。Discordが設定している高いパフォーマンス基準(メモリが5%低下したり、クラッシュが1%増加したりするとビジネスに影響が出る)を満たすのに時間がかかりました。
- 期待される効果: 移行により、CPUの改善や、特に新しいレンダラーによると思われるジャンク(コマ落ち)の劇的な改善といったパフォーマンス向上が見られています。
5. 開発環境とコミュニティへの関与
- 技術スタック: DiscordはExpoを使用していませんが、これはExpoよりも前から開発を始めていたためです。主な技術として、TypeScript、ステート管理にFlux、そしてReanimated、React Native Screensなどを使用しています。
- インフラストラクチャ: リリースパイプラインは自社で構築しています。
- 熱心なユーザーベース: Discordは非常に情熱的なユーザー層を持っており、100万人以上のAndroidベータテスターがいます。彼らはリリース後すぐに問題点を報告してくれるため、非常に貴重なフィードバック源となっています。
- コミュニティへの還元: 今後数ヶ月、数年にわたり、オープンソースへの貢献や知識の共有を通じて、コミュニティへの関与を強化していく意向です。
iOSでは早くからReact Nativeが利用されていた一方、AndroidではHermesが登場するまでパフォーマンス面で満足できず、両プラットフォームでの展開には長い時間がかかったのですね。
私が仕事でReact Nativeの採用を決めたのも、Discordのように大規模なサービスでの利用実績が大きな理由でした。 実際に自分で使ってみてもパフォーマンスが気にならなかった点も決め手です。
今回の話を聞いて、React Nativeの地道な改善と活発なコミュニティが、現在の成功を支えているのだと改めて感じました。
また、必要な部分ではNativeコードをためらわずに活用する戦略は、まさにReact Nativeの強みだと思います。 それぞれで作られた画面を一つのアプリに統合しても、ユーザーに違和感を与えない点は非常に大きなメリットです。
それにしても、Androidだけで100万人以上のベータテスターがいるとは、Discordの規模の大きさに驚かされますね…!