はじめに
Airbnb は 2016 年に React Native という大きな船に乗り込み、非常に代表的な先駆者となりました:
In 2016, we took a big bet on React Native. Two years later, we're ready to share our experience with the world and show what's next.
しかし 2018 年初頭にReact Native の終了を発表しました:
Due to a variety of technical and organizational issues, we will be sunsetting React Native and putting all of our efforts into making native amazing.
React Native を全面的に受け入れることから Native に回帰するまで、この間に何が起こったのでしょうか?
React Native に賭ける
人手が足りず、別の道を探さざるを得ませんでした:
Back then, we recognized how important mobile was becoming to our business but simply didn't have enough mobile engineers to reach our goals.
そして新しい選択が React Native でした:
We saw React Native as an opportunity to open up mobile development to more engineers as well as ship code more quickly by leveraging its cross-platform nature.
Facebook が React Native を作った初衷 と同じように、Airbnb も React Native 技術を活用してより速く動き、1 つの製品機能のために 2 つのモバイルプラットフォームコードを開発する必要がないことを望んでいました。しかし底线として、導入するこの新しい技術も Native の既定の品質基準に到達することを望んでいました
実際、React Native は確かに Airbnb の最初の期待に到達しました:
Many of these features were built at a time where we simply did not have enough native engineers to achieve our goals.
しかし利益があるだけで害がないわけではなく、深い応用の中で 2 つの難題を発見しました:
-
Native の複雑な機能との統合:共有要素トランジションアニメーション、パララックス効果、ジオフェンシングなど
-
Native の既存のインフラとの連携:ネットワーク、実験テスト、国際化など
喜びと痛み
However, its benefits didn't come without significant pain points.
Airbnb の実践経験から、React Native の利点は以下の通りです:
-
クロスプラットフォーム:さらに 3 エンドのデザイン言語の統一、および Web と Native のコードの高度な复用を実現
-
JS エコシステムへの適合:Redux、ESLint、Prettier、reselect、jest などの JS エコシステムにシームレスに接続
-
開発効率:コンパイルを待つ必要がなく、Flexbox レイアウトも習得しやすい
-
Native 拡張:あらゆる Native 機能を React Native にブリッジでき、同時に Native の既存のインフラも統合可能
-
許容範囲内のパフォーマンス:アニメーションは Native と同様にスムーズで、体験はほとんどのシナリオを満たし、パフォーマンスを気にすることはほとんどない
クロスプラットフォーム特性がもたらすコード复用と 3 エンド統一の可能性は代替不可能な利点であり、JavaScript ランタイムを��ポートすることで JS エコシステムに参入し、Hot Reloading などのコンパイル不要の体験を獲得し、開発効率の向上を実現しています
実際、広く注目されているパフォーマンス問題は、想像ほど遅くありません:
We frequently saw mobile engineers look at JS and think"slower than Java". However, moving business logic and layout off of the main thread actually improves render performance in many cases.
能力の境界に触れるシナリオでは、Native Bridge を通じて制限を打破できます:
Because everything in React Native can be bridged by native code, we were ultimately able to build many things we weren't sure were possible at the beginning such as Shared element transitions, Lottie, Native networking stack, i18n, experimentation, etc.
完璧に見えます。しかし別の側面では、React Native は確かに多くの苦痛をもたらしました、例えば:
-
自身の成熟度が不十分:Android、iOS ほど成熟しておらず、不確かな能力境界のリスクが存在
-
JS 言語の不足:弱型によりリファクタリングが困難でエラーが発生しやすい(初期には TypeScript サポート が提供されていなかった)
-
ライブラリ構築の敷居が高い:React Native ライブラリを作成するには 3 つのプラットフォームを理解する必要があり、否则プラットフォーム固有の問題が発生しやすく、開発者への要求が非常に高い
-
一部の機能のサポートが不十分:例えば重厚な Native Bridge API、初期に提供されたアクセシビリティ API が不健全、長い List のサポートが Native 方案ほど成熟・柔軟ではない、ジェスチャーサポート、JS ランタイム環境にプラットフォームの差異……さらに長らく Android 64 ビットをサポートせず(2019 年 3 月の 0.59 バージョンでようやく Android 64 ビットをサポート)
-
初画面パフォーマンスの致命的欠陥:秒単位のランタイム初期化オーバーヘッド、および数百ミリ秒の前置き初画面レンダリング時間、フラッシュスクリーンなどのシナリオのパフォーマンス要件を全く満たせない
-
追加の負担:React Native の導入はパッケージサイズを 8〜12MB 増加させることを意味し、同時にエコシステムがまだ成熟していないため、開発中は通常インフラと機能イテレーションを並行して行う必要がある
技術自体の成熟度が不十分で、(ライブラリ構築の敷居の高さによる)オープンソースエコシステムの発展が遅いため、実際の使用では急速にパッチを当てる必要があるシナリオに対応するために、通常は独自の React Native を維持する必要があり、この部分の維持コストは軽視できません:
We had to maintain our own fork of React Native where we could merge fixes. For these case, a one-line fix on Android or iOS wound up taking days of figuring out how to add it to React Native, cherry picking it, then filing an issue on React Native core and following up on it over the coming weeks.
別の側面では、Native が多年にわたり蓄積したインフラ(クラッシュモニタリングなど)はすべて React Native で再構築(書き直しまたはブリッジ)する必要があり、否则開発体験と効率は追いつきません:
Because React Native is relatively new and rare in the industry, we had to build a significant amount of infrastructure.
初画面パフォーマンスの主な難点は以下の通りです:
-
初期化時間:React Native ランタイムの初期化オーバーヘッドは避けられず、大規模アプリケーションでは(2018 年の)ハイエンドデバイスでも数秒を要する
-
レンダリング開始の前置き時間:JS スレッド、yoga レイアウトスレッドを経て、十分な情報を取得してからメインスレッドでレンダリングを開始でき、この間に 280〜440ms のホワイトスクリーン時間が存在
P.S.スレッドモデルの制限は別の問題ももたらしました、例えば:
Many of the limitations are difficult to overcome because of the threading. Adapter data can't be accessed synchronously so it is possible to see views flash in as they get asynchronously rendered while scrolling quickly. Text also can't be measured synchronously so iOS can't make certain optimizations with pre-computed cell heights.
チーム組織はどうやってクロスプラットフォーム化する?
We learned a ton about what React Native means for an engineering organization. Adopting it is much more complex than adding a new library or pattern to an existing platform.
技術も組織構造に影響を与え、これらの課題は技術問題よりも解決が難しいかもしれません
エンジニアへの要求
-
3 エンドの体験をバランス:React Native の本質は依然として Native であるため、Native インフラは不可欠であり、プラットフォームの差異は依然として存在し、これにより 3 エンドの体験をバランスすることが非常に困難になる
-
チームを跨いだ問題定位:React Native 自体が急速に発展変化しており、インフラと機能イテレーションが並行し、さらに皆があまり経験を持っていないため、問題定位が異常に困難になり、問題がどのチームに帰属するのか、それとも上流の React Native からのものなのか分からないことさえある
-
クロスプラットフォームの複雑さに対応:エンジニアはほとんどが 1〜2 つのプラットフォームに精通しており、構築またはデバッグ時に他のプラットフォーム涉及する可能性がある。さらに悪いことに、このようなクロスプラットフォームの複雑さに直面し、エンジニアは問題从何から調べ始めるべきか全く分からない可能性がある
-
3 セットの開発環境を準備:React Native エンジニアは 3 セットの最新の開発環境を備える必要があり、各セットの環境はそれほど簡単に構築・学習・更新を維持できず、数週間ごとに数時間を費やしてこれらの環境を更新する必要がある
React Native はプラットフォームの差異を完全に隠蔽できないため、エンジニアにこれらの差異を理解し、慎重に 3 エンドの体験をバランスすることが要求されます。クロスプラットフォームによる複雑さは直接問題調査リンクに現れ、エンジニアはチームを跨ぎ、技術スタックを跨いで問題を定位する必要があるかもしれません
チーム組織が直面する課題
チームはメンバーの体感上のいくつかの問題に直面する可能性があります、例えば:
-
態度が両極分化:実践経験によれば、エンジニアがこの技術を受け入れる程度には両極分化が存在し、これを 3 エンド統一の銀弾と見なして全力でサポートする者もいれば、全く拒否して少しも使いたがらない者もいる
-
知覚上のイテレーション速度の低下:エンジニアの視点から見ると、Native と比較して React Native で特定の機能を開発するのに 1.5 倍の時間が必要な場合、彼は依然により長い���間を費やしたと考える、事実(マルチプラットフォーム)合計で費やした時間が減少しているにもかかわらず
混合技術スタックの下で、チームはいくつかの新しい問題を考慮する必要があります:
-
チームをどう划分し、どう協力するか?
-
どう効率的に技術スタックを跨いでデバッグするか?
-
どうクロスプラットフォームでテストし、コードがマルチプラットフォームで正常に動作することを保証するか?
-
どう新機能をどの技術で実装するか決定するか?
-
どうチームリソースを募集し配分するか?
実際、このような混合技術スタックは確かに人員募集、チーム划分、技術実装、トレーニング教学などに一連の影響を与えました:
-
人員募集:業界は企業に React Native のラベルを貼り、多くのエンジニアがこのため加入を躊躇し、人員募集に影響
-
チーム划分:混合チームは頻繁に技術とコミュニケーション上の問題に直面する、コードが 2 つに分割され、エンジニアがもはや論理フロー全体に精通していないため、ビジネスロジック、モデル、状態などを共有することが非常に困難になる。これらの問題はリソースとコードを共有することで解決できるが、多数のチームはまだこのような良好な雰囲気を形成していない
-
複数技術スタックのバランス:どのコードを Native で実装すべきか、どれを React Native に置くべきかは、权衡する必要がある。エンジニアは通常これらを考慮せず、自分が慣れた技術スタックを使用する傾向があり、一部のコードがそれほど理想的ではなくなる
-
トレーニング教学:Native の 10 年以上のリソース蓄積と比較して、React Native 関連の学習リソースとドキュメントは依然として少なすぎる、技術および内部インフラの教学トレーニングにいくつかのリソースを投入する必要がある
React Native を放棄し、Native に回帰
Although many teams relied on React Native and had planned on using it for the foreseeable future, we were ultimately unable to meet our original goals.
2 年の実践検証を経て、React Native が最初の期待を完全に満たせないことを確認:
-
Move Faster:順調な時は、開発速度は確かに比類なきものだが、様々な技術上および組織上の問題がこの速度を大きく遅らせた
-
Native の既定の品質基準に到達:React Native の不断の成熟と実践中に蓄積した経験はいくつかのパフォーマンス向上をもたらしたが、いくつかの技術問題(初期化と初画面非同期レンダリングなど)は依然として挑戦に満ちており、内部外部のリソースの欠乏がこの困難を悪化させた
-
1 つの製品機能のためにプラットフォームごとに 2 セットのモバイルコードを開発する必要がない:React Native コードはほとんどクロスプラットフォームで复用できるが、Airbnb App ではこの部分のコードの割合は非常に小さく、さらに大量のインフラをブリッジする必要があるため、実際の結果は Android、iOS、React Native の 3 つのプラットフォームで開発する必要があり、Native 二重プラットフォームだけでなく
-
開発体験の向上:開発体験は言い難く、コンパイル時間の表現は良かったが、デバッグ体験は非常に悪かった
以上の种种により、熟慮の末、Airbnb は最後に React Native を全面的に放棄することを決定:
When we balanced the positives against the pain points plus the current needs and resources of our Engineering organization, we decided that it wasn't right for us anymore.
具体的には、2018 年 6 月から、すべての機能イテレーションは React Native 技術を考慮せず、関連するオープンソースプロジェクトも維持せず、2018 年末までに高トラフィックビジネスをすべて Native で実装するよう移行し、React Native がもたらすパフォーマンス負担(起動時の初期化時間など)を徐々に除去する計画
React Native の啓発を受けた Native 開発
React Native の継続使用を放棄したが、この 2 年間で、Airbnb はいくつかのNative にとって非常に価値のある啓発を受けた:
Today, we have a number of exciting projects in production or in the pipeline. Some of these projects were inspired by the best parts and learnings from our experience with React Native.
例えば:
-
Server-Driven Rendering:動的更新
-
Epoxy Components:宣言的コンポーネント定義、遅延読み込み、仮想 DOM ベースの更新メカニズム
-
MvRx:スレッドモデル
-
コンパイル速度向上:モジュール化コンパイル
Server-Driven Rendering
サービス駆動の Native レンダリング(Server-Driven Rendering):
With these frameworks, the server sends data to the device describing the components to render, the screen configuration, and the actions that can occur. Each mobile platform then interprets this data and renders native screens or even entire flows using DLS components.
動的更新などのシナリオで使用:
Server-driven rendering frameworks have already provided huge value by allowing us to experiment with and update functionality instantly over-the-air.
Epoxy Component
Epoxy は Android と iOS をサポートする宣言的 Native コンポーネント方案:
Epoxy is a framework that enables easy heterogeneous RecyclerViews, UICollectionViews, and UITableViews.
その中で、React の仮想 DOM ベースのコンポーネント更新思路を参考にしました:
The key to React's performance is that those components are just a data model representation of the actual views/HTML you want to render. The component tree is then diffed and only the changes are dispatched. We built a similar concept for Epoxy.
MvRx
汎用開発パターンおよびいくつかの React 思想を融合して形成された Android 開発フレームワーク、MvRx:
MvRx is an opinionated yet flexible framework that was developed by taking common development patterns that we observed as well as the best parts of React.
コンパイル速度
モジュールを分割してコンパイル時間を短縮:
We built infrastructure on Android and iOS to enable you to compile only part of the app that includes a launcher and can depend on specific feature modules.
なぜこんなに難しいのか?
これで、Airbnb における React Native の物語は終了しました
React Native に賭けることから、技術、チーム組織の難題に遭遇し、利弊を权衡した後に放棄を決定し、最後に全力で Native システムに投入し、React Native のいくつかの思路を応用するまで……なぜこんなに難しいのか?大企業でさえこの新しい技術を驾驭できないのか?
客観的に言えば、Airbnb が遭遇した多くの困難は Native と React Native の混合応用に由来する(React Native を既存の Native App に統合):
We integrated React Native into large existing apps that continued to move at a very fast pace. Many of the difficulties we encountered were due to the hybrid model approach we took.
Facebook は 2018 年 6 月 になってようやく大規模な���ファクタリングを通じて混合応用中に存在する様々な問題を解決することを計画:
We're working on a large-scale rearchitecture of React Native to make the framework more flexible and integrate better with native infrastructure in hybrid JavaScript/native apps.
これらの問題の中の多くの難点は Airbnb が経験し、それらと絶えず闘争してきたものだ。一些小規模企業と比較して、Airbnb はより深く遠くまで進む能力があったため、より多くの大きな難題に遭遇しました:
However, our scale allowed us to take on and solve some difficult problems that smaller companies may not have had time to solve.
早期の信者である Airbnb は放棄を選択したが、React Native は引き続き高速に発展し、日増しに成熟している:
Facebook and the broader React Native community are dedicated to making React Native work for hybrid apps at scale. React Native is progressing faster than ever.
したがって、多くの他の企業(Pinterest、Instagram など)にとって、React Native は依然として素晴らしい、あるいは最良の選択である
コメントはまだありません