├── 1-alt-react-native-at-airbnb.md ├── 2-react-native-at-airbnb-the-technology.md ├── 3-building-a-cross-platform-mobile-team.md ├── 4-sunsetting-react-native.md ├── 5-what’s-next-for-mobile-at-airbnb.md └── README.md /1-alt-react-native-at-airbnb.md: -------------------------------------------------------------------------------- 1 | > 2016年から私達はReact Nativeに対して大きな投資を続けてきました。 2 | > 3 | > あれから2年の歳月が経ち、今こそ私達が取り組んできた試みと次に何を見据えているかを皆さんと共有すべき時だと判断しました。 4 | 5 | 本稿は私達AirbnbのReact Nativeへの取り組みとモバイルの"次"についてまとめたシリーズの第一弾となります。 6 | 7 | Airbnbがサービスを開始した10年前、スマートフォンはまだ普及し始めたばかりでした。それから幾ばくが経ち、世界を旅行する人が増えるに従ってスマートフォンは今や私達の生活を支える必要不可欠なツールとなりました。新たな旅の形を提供する会社として、世界に通用するアプリを提供する事はとても重要な事だと認識しています。携帯端末はしばしば人々にとって必要不可欠な存在であり、外出している際の唯一の連絡手段でもあります。 8 | 9 | 2008年に(Airbnbの最初のユーザーである)3人のゲストがRausch Streetに滞在してから、携帯端末からの(Airbnbへの)予約数は年間で数百万件にまで増加しました。我々のアプリを通してホストは提供している物件の一覧を管理する事ができ、旅人は新たな場所や体験を発見するインスピレーションを指先一本で得る事ができます。 10 | 11 | (上記で説明した様な)増加していくモバイル端末でのユースケースに対応する為、また新たな体験の創出や既存機能の改善を図るために私達はNativeの開発チームを100人以上に拡大してきました。 12 | 13 | ### React Nativeへの賭け 14 | 15 | ゲストとホスト双方がAirbnbで素晴らしい体験を得られるように、また優れた開発者体験を(社内のエンジニアに)もたらせるように私達は日々新たなテクノロジーを検証しています。2016年時点で、その内の一つがReact Nativeでした。当時、我々はモバイルが如何に我々のビジネスにとって重要なものになっていたかを認識していましたが、我々の目標を達成する為に十分な数の開発者を揃える事ができていませんでした。結果として我々は(Nativeで開発する以外の)代替案を検討するようになったのです。我々のWebサイトは主にReactで書かれており、Reactはとても効率的でAirbnb社内でもあまねく支持を得ているフレームワークです。これらの理由から、我々はReact Nativeをより多くの開発者に開発の間口を広げる為の、そしてクロスプラットフォーム開発でリリースをより高速に届ける為のツールとして見据えていました。 16 | 17 | 私達がReact Nativeについての調査を開始した時、当然そのリスクについても認識していました。私達は新しく、先の読めない実績がないプラットフォームを我々のコードベースに追加したのです。それは我々のコードベースを一つのものにするどころか、断片化するリスクを孕んだ決断でした。また、我々は同時にReact Nativeに投資をするのであれば(投資という行為自体を)しっかりとやっていきたいと思っていました。我々がReact Nativeを用いて実現したいゴールは以下のようなものです。 18 | 19 | - 組織としてスピード感を持って動けるようにする事 20 | - "Native"の品質を維持する事 21 | - クロスプラットフォーム開発を実現する事(コードをiOSとAndroidで二回書かない事) 22 | - 開発者の体験を向上させる事 23 | 24 | ### 我々の体験 25 | 26 | 2年に渡る試みはいつしか真摯な努力になっていました。私達はネットワーキングやABテスト、I18nなどのインフラストラクチャ bridgeを構築するだけでなくshared element transitionsやparallaxエフェクト、ジオフェンシングなど複雑なNativeの機能を実現する為の確固たるインテグレーションを実現してきました。 27 | 28 | 我々はAirbnbの沢山の重要な機能をReact Nativeを用いて立ち上げてきました。"Experiences"という全く新たなビジネスやレビューやギフトカードなど多くの機能はそのうちの一つです。これらの多くの機能はNativeエンジニアが不足している時代に(同時に)構築されたものです。 29 | 30 | それぞれのチームが多種多様な体験をReact Nativeと共に積んできました。React Nativeは素晴らしいツールになりうるという事が証明された一方で、それは技術的そして組織的な挑戦を投げかける存在でもありました。 31 | 32 | 本シリーズでは私達の体験を余す所なくお伝えし、次に何に取り組んでいるかも同時にお伝えします。 33 | 34 | [Part two](https://medium.com/airbnb-engineering/react-native-at-airbnb-the-technology-dafd0b43838)([日本語訳](https://github.com/react-native-jp/react-native-at-airbnb-jp-translation/blob/master/2-react-native-at-airbnb-the-technology.md))では、React Nativeで(技術的に)うまくいった所、うまくいかなかった所を振り返ります。 35 | 36 | [Part three](https://medium.com/airbnb-engineering/building-a-cross-platform-mobile-team-3e1837b40a88)([日本語訳](https://github.com/react-native-jp/react-native-at-airbnb-jp-translation/blob/master/3-building-a-cross-platform-mobile-team.md))では、クロスプラットフォームなモバイルチームを作るに当たって取り組んだ組織的な挑戦を振り返ります。 37 | 38 | [Part four](https://medium.com/airbnb-engineering/sunsetting-react-native-1868ba28e30a)([日本語訳](https://github.com/react-native-jp/react-native-at-airbnb-jp-translation/blob/master/4-sunsetting-react-native.md))では、我々とReact Nativeの現在の状況に焦点を当て、AirbnbにおけるReact Nativeがどうなるであろうかをお伝えします。 39 | 40 | [Part five](https://medium.com/airbnb-engineering/whats-next-for-mobile-at-airbnb-5e71618576ab)([日本語訳](https://github.com/react-native-jp/react-native-at-airbnb-jp-translation/blob/master/5-what%E2%80%99s-next-for-mobile-at-airbnb.md))では、React Nativeから学んだ事とそれらをNative開発にどの様に役立てているかをお話します。 41 | -------------------------------------------------------------------------------- /2-react-native-at-airbnb-the-technology.md: -------------------------------------------------------------------------------- 1 | この記事はAirbnb社におけるReact Native体験と `次の時代`のモバイルアプリケーション開発について記したブログシリーズの第二弾です。 2 | 3 | React NativeはAndroid, iOS, Webで横断的に動作する、それ自体が比較的新しく急速に発展しているクロスプラットフォームフレームワークです。2年間に渡って使ってきた今、React Nativeは多くの点において革新的なツールであると自信を持って言えます。それはモバイル開発におけるパラダイムシフトであり、私たちはReact Nativeが掲げるゴールから多くの恩恵を受けることができました。しかしその利点を得るために多くの痛みが伴ったことは無視できません。 4 | 5 | ## 上手くいったこと 6 | ### クロスプラットフォーム 7 | React Nativeを利用することによる一番の利点は一度書いたコードがAndroidでもiOSでも動作するということです。React Nativeで実装した機能の多くでは95-100%のコードを共有することができ、 プラットフォームに依存したファイル(\*.android.js/\*.ios.js)は0.2%にすぎませんでした。 8 | 9 | ### 共通のデザイン言語システム(DLS) 10 | 私たちは[DLS](https://airbnb.design/building-a-visual-language/)と呼ばれるクロスプラットフォームのデザイン言語を開発しており、Android、iOS、React Native、Web、それぞれのバージョンがコンポーネントごとに存在しています。共通のデザイン言語を持つことで一貫したデザイン、コンポーネント名、そして画面を持てるようになり、それによってクロスプラットフォーム機能を書くことが可能となったのです。 11 | 12 | しかし同時に必要に応じてプラットフォーム固有のデザインを適用することもまた可能でした。例えばAndroidにおいて[Toolbar](https://developer.android.com/reference/android/support/v7/widget/Toolbar)を利用するがiOSでは[UINavigationBar](https://developer.apple.com/documentation/uikit/uinavigationbar)を使う、Andoroidではプラットフォームのデザインガイドラインに適さない[disclosure indicators](https://developer.apple.com/ios/human-interface-guidelines/views/tables/)を隠すなどといったことです。 13 | 14 | 私たちはネイティブのコンポーネントをラップするのではなく、React Nativeでコンポーネントを書き直す方法を選択しました。なぜならその方が個別にプラットフォーム固有のAPIを叩く上で信頼性が高く、React Native上での変更をテストする手段に詳しくないネイティブエンジニアのメンテナンスにおけるオーバーヘッドを削減できるからです。ただしこのアプローチはネイティブとReact Native間でのバージョンの乖離を引き起こすこととなりました。 15 | 16 | ### React 17 | Reactが[最も愛される](https://insights.stackoverflow.com/survey/2018/#technology-most-loved-dreaded-and-wanted-frameworks-libraries-and-tools)Webフレームワークと呼ばれるのには理由があります。シンプルかつ強力で、より大きなコードベースへスケールしやすいからです。特に私たちが気に入っている点としては、 18 | 19 | - *Components:* 適切に定義されたpropsとstateによってReact Componentは開発における関心の分離を実現します。これはReactのスケーラビリティにおける大きな要因です。 20 | - *簡潔なライフサイクル:* Androidと(多少はマシですが)iOSのライフサイクルは非常に複雑なことで知られています。適切に動作するリアクティブなReact Componentはこの問題を根本的に解決するため、React Nativeの学習をAndroidやiOSのそれと比べて非常に容易にしています。 21 | - *宣言的:* Declarative(宣言的)であるというReactの特徴は、内部のstateとUIの整合性を保つ上でとても役に立ちます。 22 | 23 | ### 検証スピード 24 | React Nativeを利用することでアプリケーションの変更を即座に確認できる[hot reloading](https://facebook.github.io/react-native/blog/2016/03/24/introducing-hot-reloading.html)を活用することができます。ビルドパフォーマンスはわたしたちのネイティブアプリでの最優先課題でしたが、React Nativeで達成したイテレーションスピードに近付くことすらできませんでした。ネイティブのビルドは最速で15秒でしたが、フルビルドで20分かかることもありました。 25 | 26 | ### インフラへの投資 27 | 私たちはネイティブのインフラに対して広い範囲でのIntegrationを実現しました。'networking', 'i18n', 'experimentation', 'shared element transitions', 'device info', 'account info'というコア機能をはじめとした多くの機能が個別のReact Native APIとしてラップされました。既にあるAndroidやiOSのAPIをReactのために整合性を持たせたり正規化する必要があったため、それらのBrdigeはとても複雑なパーツとなりました。高速な開発サイクルの中でこれらのBridgeを常に最新の状態に保つ作業が必要になりましたが、インフラチームがこの部分に投資してくれたことによってプロダクト開発がずっと容易になりました。 28 | 29 | このインフラ部分への大きな投資がなければ、React Nativeによる開発はもっと中途半端なものなっていたでしょう。React Nativeを既存のアプリにつっこむためには、このような投資が必要不可欠だろうというのが私たちの結論です。 30 | 31 | ### パフォーマンス 32 | React Nativeにまつわる最も大きな心配事の一つがパフォーマンスの問題です。ですが実際はほとんど問題になることはなく、React Nativeで実装した多くの画面がネイティブと遜色なく動作しました。パフォーマンスというものは一面的に捉えられがちです。ネイティブエンジニアがJSに対して「Javaより遅い」と考えているのをよく見かけますが、ビジネスロジックや[layout](https://github.com/facebook/yoga)をメインスレッドから分割することで描画のパフォーマンスが向上することは多々あります。 33 | 34 | パフォーマンスの問題が発生することもありましたが、大抵は過度な描画によるもので[shouldComponentUpdate](https://reactjs.org/docs/react-component.html#shouldcomponentupdate)や[removeClippedSubviews](https://facebook.github.io/react-native/docs/view.html#removeclippedsubviews)を活用したりReduxの使い方を改善することで和らげることができました。 35 | 36 | しかしながら初期化処理と最初の描画時間に関するパフォーマンスは低くReact Nativeで作った起動画面やディープリンク、画面回遊時のTTIなどに大きな影響を与えました。それに加えて[Yoga](https://github.com/facebook/yoga)がReact Native coponentをネイティブのviewに変換するため、スクリーンフレームの低下時にデバッグするのが難しいという問題もありました。 37 | 38 | ### Redux 39 | stateとUIの整合性を保ちやすい、画面をまたいだデータの共有が簡単に行える等の有用性から私たちはReduxを採用しました。ですがReduxは悪名高いboilerplateで知られ、学習の難易度も高いです。一般的なテンプレートを生成するジェネレータも用意しましたが、ReduxはReact Nativeで開発する上で最も難しい部分であり混乱を招きやすい部分であることに変わりはありませんでした。React Nativeに限った問題ではありませんが。 40 | 41 | ### ネイティブの支え 42 | React Nativeの中で起きる全てのことはネイティブのコードにBridgeできるため、開発を始めた時点では実現可能か確信の持てなかった多くのものを最終的に実現することができました。 43 | 44 | 1. *Shared element transitions:* 私たちはAndroidとiOSのネイティブコードと連携した ``コンポーネントを開発しました。これはネイティブとReact Nativeのスクリーン間でも利用できます。 45 | 2. *Lottie:* AndroidとiOS向けのライブラリをラップすることでLottieをReact Native上で動かすことが可能になりました。 46 | 3. *ネットワーク機構:* React Nativeは既存のわたしたちのネイティブの通信スタックとキャッシュ機構を利用します。 47 | 4. *その他のコアインフラ:* Networkingだけでなく、'i18n'や'experimentation'のようなその他のネイティブインフラもラップすることでReact Nativeからシームレスに利用できます。 48 | 49 | ### 静的解析 50 | AirbnbはWebでの[eslintの利用](https://github.com/airbnb/javascript)について確固とした実績を持っていますが、[prettier](https://github.com/prettier/prettier)を導入したのは私たちのプラットフォームが社内では初めてでした。prettierはPull Requestにおける細かな指摘やミスを軽減するのにとても有効で、Webインフラチームでは活発に試されています。 51 | 52 | また描画にかかる時間とコストを解析することで、改修の優先度が高い画面を調べています。 53 | 54 | React Nativeは私たちのwebインフラストラクチャよりも新しく小さかったため、新しいアイディアを試すのに持ってこいであることが分かりました。React Nativeのために開発した多くのツールやアイディアが今ではWebにも持ち込まれています。 55 | 56 | ### アニメーション 57 | React Nativeの[アニメーションライブラリ](https://facebook.github.io/react-native/docs/animated.html)のおかげで効果的なアニメーションを実装可能になり、スクローリングやパララックスなどインタラクションドリブンなアニメーションも手に入れました。 58 | 59 | ### オープンソース 60 | React NativeではReactとJavaScriptという巨人の肩に乗ることで、redux,reselect, jestといった膨大な数のJSプロジェクトの恩恵を受けることができます。 61 | 62 | ### Flexbox 63 | C言語で書かれたクロスプラットフォームなライブラリであり[Flexbox](https://www.w3schools.com/css/css3_flexbox.asp) APIによるレイアウト計算を行う[Yoga](https://github.com/facebook/yoga)をReact Nativeでは利用しています。はじめこそアスペクト比が使えないなどYogaの機能的制限に悩まされましたが、その後のアップデートで解決されました。[flebox froggy](https://flexboxfroggy.com/)のような楽しいチュートリアルもオンボーディングで活躍しています。 64 | 65 | ### Webとのコラボレーション 66 | 開発が進むにつれて最近ではWeb, iOS, Androidの開発を一度に行えるようになりました。WebでもReduxが使われていることからWebとネイティブで広範囲に渡るコードを、特別な調整なしで共有できることに気が付いたのです。 67 | 68 | ## 上手くいかなかったこと 69 | ### React Nativeの未熟さ故の問題 70 | 新しく、野心的で、急速に発展してはいますがReact NativeはAndroidやiOSに比べてまだまだ未成熟なプラットフォームです。多くの状況でReact Nativeは上手く機能する一方、その未熟さが透けて見え、ネイティブではすぐに解決できるような些細な問題がとても難しくなってしまうことがあります。残念ながらこれらのケースは予測が難しく、ワークアラウンドを行うのに数時間で終わることもあれば何日もかかることもあります。 71 | 72 | ### Forked React Nativeのメンテナンス 73 | React Nativeは未成熟であるため場合によってはソースコードに修正を加える必要があります。すぐに修正を反映するためにはReact Native本体にコントリビュートするのみでなく、Forkした[独自のレポジトリ](https://github.com/airbnb/react-native/commits/0.46-canary)を用意して管理する必要がありました。この2年間でReact Nativeの上にさらに約50個ほどコミットを積みましたが、これによってReact Nativeのアップデートが恐ろしく大変なものとなったのです。 74 | 75 | ### JavaScriptツール 76 | JavaScriptは動的型付けの言語です。型安全でない言語を扱うことはスケールが難しいだけでなく、型のある世界からやってきたネイティブエンジニアとの争いの元となりました。彼らは型の問題がなければよりReact Nativeの学習に興味を示してくれたでしょう。 77 | 78 | 私たちは[flow](https://flow.org/)の導入を試みましたが、まるで暗号のようなエラーメッセージに開発者のフラストレーションはたまる一方でした。[TypeScript](http://www.typescriptlang.org/)も調査はしましたが、既にある[babel](https://babeljs.io/)や[metro bundler](https://github.com/facebook/metro)との統合に問題があります。そのような状況ではありますが、今後も私たちはweb向けにTypeScriptの調査を継続していくつもりです。 79 | 80 | ### リファクタリング 81 | JavaScriptという型のない言語を扱った結果、リファクタリングがとても大変な作業になり多くのエラーが吐かれることとなりました。props名の変更、特に複数のコンポーネントにまたがって継承される `onClick`のような広く使われるpropsを正確に変更する作業はまるで悪夢のようでした。更に悪いことに、そのようなリファクタはコンパイル時でなくプロダクション時にエラーになり、静的解析を適用するのも難しいものでした。 82 | 83 | ### JavaScriptCoreの不安定性 84 | React Nativeのトリッキーな特徴としては、それが[JavaScriptCore environment](https://facebook.github.io/react-native/docs/javascript-environment.html)で実行されるということです。それによって以下のような問題に直面しました。 85 | 86 | - iOSは初期状態で[独自のJavaScriptCore](https://developer.apple.com/documentation/javascriptcore)を持っているため動作も概ね安定しており、大きな問題はありませんでした。 87 | - Androidは自前のJavaScriptCoreを持たないため、React Nativeが自身のものをバンドルすることで実行環境が作られます。問題なのはこのランタイムがとてつもなく[古い](https://github.com/facebook/react-native/issues/10245)ものであるということです。結果的に私たちは新たに自前で新しい[JSC](https://github.com/react-community/jsc-android-buildscripts)をバンドルしてやる必要がありました。 88 | - React Nativeはデバッグ時にパワフルなChrome Developer Toolsに接続します。素晴らしい!ですがデバッグモードに入ると同時に、React NativeのコードはChromeのV8エンジンで実行されるようになります。99.9%のケースでは特に問題はないのですが、ただ一度だけ、 `toLocaleString`メソッドがAndroidではデバッグモードでしか動かないという問題に引っかかりました(iOSは大丈夫でした)。どうやらAndroidのJavaScriptCoreにメソッドが[含まれておらず](https://github.com/facebook/react-native/issues/15717)、そこでエラーも吐かずに落ちていたようです。当然デバッグ時に利用するV8環境では動作していました。このような問題に対処できる深い技術的知識がなければ、何日も現場のエンジニア達は悩まされることになるでしょう。 89 | 90 | ### React Native向けのオープンソースライブラリ 91 | 任意のプラットフォームについて学び、習熟するのには長い時間がかかります。多くの人は1つまたは2つのプラットフォームについてのみしか理解してないと言えるでしょう。mapやvideoといったネイティブとのbrdigeを持ったReact Nativeライブラリを開発するには3つ全てのプラットフォーム知識が求められます。残念ながら多くのReact Native向けオープンソースライブラリの開発者はそのうちの1つか2つのプラットフォームしか経験していませんでした。それはAndroidもしくはiOSにおける不整合や予期しないバグを引き起こしました。 92 | 93 | Android向けの多くのReact Nativeライブラリではパッケージの読み込みにmavenではなくnode modulesの相対パスによる記述を要求しますが、これはコミュニティの期待する方法とは一貫しないやりかたです。 94 | 95 | ### インフラの二重管理と機能開発 96 | 私たちは長年に渡ってAndroidとiOSにおけるネイティブのインフラストラクチャを構築・蓄積してきましたが、React Nativeに向けて全ての既存のインフラに対するBridgeをゼロから作成する必要がありました。つまりエンジニアが新しい機能を開発する際に、よく理解していないプラットフォームに対して自らのプロジェクトのスコープ外の作業を行ってbridgeを作るか、それが作れるようになるまで待つ必要があったのです。 97 | 98 | ### クラッシュレポート 99 | 私たちはネイティブランタイムでのクラッシュレポートに[Bugsnag](https://www.bugsnag.com/)を利用しています。AndroidとiOSのどちらのプラットフォームでも大抵は動作する一方で、あまり信頼性は高いとは言えず、また他のプラットフォームに比べて多くの作業が必要でした。React Nativeは新興であるが故に、私たち自身の手でsource mapアップロードのようなインフラを大量に作成したり、BugsnagがReact Nativeで起きた問題のみをトラックできるようなフィルタリング機能を追加する必要がありました。 100 | 101 | このように多くのインフラレベルの機能をReact Nativeに実装しなければいけない状況下であるため、クラッシュしたのにレポートが送信されない、source mapが適切にアップロードされないといった問題に悩まされることになりました。 102 | 103 | もう一つ付け加えると、ネイティブとReact Native間でスタックトレースは別れてしまうため、双方を跨いだ問題のデバッグはとても大変なものになるでしょう。 104 | 105 | ### ネイティブブリッジ 106 | React Nativeにはネイティブと通信するための[bridge API](https://facebook.github.io/react-native/docs/communication-ios.html)があります。このAPIは期待通りの動作をしてくれるものの、実装するのがものすごく面倒です。まず初めに3つのプラットフォーム向けのそれぞれの開発環境を適切に設定する必要があります。JavaScriptから返ってくるデータ型が予測不可能という問題もあります。例えばinteger型はしばしばstring型にラップされてしまい、bridgeを通ってみるまでどうなるのか分かりません。またAndroidではクラッシュするのにiOSではフィードバックもなく落ちることがあります。私たちは2017年の終わりにかけてTypeScriptの型定義ファイルからbridgeコードを自動生成する方法に取り組みましたが、それはかけるコストも少なすぎ、タイミングも遅すぎました。 107 | 108 | ### 初期化の時間 109 | React Nativeがファーストビューを描画するには、まずその前にランタイムを初期化する必要があります。残念ながら私たちほどの規模になると、たとえそれがハイエンドデバイスであっても数秒かかってしまいます。このような問題があるなかでReact Nativeをアプリの起動画面に採用することはほぼ不可能です。私たちはアプリの起動時にReact Nativeの初期化を行うことでファーストビューの描画にかかる時間を最小化しました。 110 | 111 | ### ファーストビューの描画時間 112 | ネイティブの場合とは異なりReact Nativeでファーストビューに必要な情報をあつめて描画するためには、メインスレッド -> JS -> yogaレイアウトスレッド -> メインスレッドというサイクルを実行する必要があります。ファーストビューを描画するまでの時間の90パーセンタイルの平均はiOSで280ms、Androidで440msでした。Androidでは[postponeEnterTransition API](https://developer.android.com/reference/android/app/Activity.html#postponeEnterTransition%28%29)を利用しています。通常はshared element transitionにおいて描画までのディレイを適用するために使われるものです。iOSにおいてはNavBarの設定にReact Nativeだと時間がかかりすぎるという問題がありました。最終的に私たちはnavbarの設定が読み込まれるまではインタラクションが発生しないよう、全てのReact Nativeでのページ遷移に50msのディレイをかけることにしました。 113 | 114 | ### App Size 115 | React Nativeによるアプリケーションサイズへの影響も無視できません。Androidの場合、React Nativeのトータルのサイズ(Java + JS + Yoga含むネイティブライブラリ + JavaScript Runtime)はABIごとに8MBとなりました。x86とarm(32bit only)を含めたAPKなら12MBほどになるでしょう。 116 | 117 | ### 64bit 118 | [この](https://github.com/facebook/react-native/issues/2814)問題により、今の所はまだAndroidに向けて64bitのAPKを配信できていません。 119 | 120 | ### ジェスチャー 121 | タッチコントロールに関するサブシステムはAndroidとiOS間での違いが大きすぎることもあり、それらを統合するAPIを開発することはReact Nativeコミュニティ全体にとって大きな課題です。そのようなこともあり現在Airbnbでは、複雑なジェスチャーを要求する画面ではReact Nativeは利用していません。しかしながら[react-native-gesture-handler](https://github.com/kmagiera/react-native-gesture-handler)のv1.0が最近リリースされるなど、まだ取り組みは活発なようです。 122 | 123 | ### リスト表示 124 | [FlatList](https://facebook.github.io/react-native/docs/flatlist.html)のようなライブラリが登場したことでReact Nativeでもこの分野が発展してきているようです。ですがそれはまだAndroidの[RecyclerView](https://developer.android.com/guide/topics/ui/layout/recyclerview)やiOSの[UICollectionView](https://developer.apple.com/documentation/uikit/uicollectionview)には到底及びません。スレッドの機構により多くの制限がなかなか解決されないでいます。Adapterのデータには同期的にアクセスできないので、素早くスクロールするとそれらが非同期的にレンダリングされて画面がちらつく可能性があります。テキストもiOSでは非同期で計測されるため、事前にCellの高さを計算することが難しいです。 125 | 126 | (* 訳注: あまり意味が理解できておらず申し訳ないです。) 127 | 128 | ### React Nativeのアップグレード 129 | React Nativeにおけるほとんどのアップグレード作業は難しくありませんが、とても大変なケースがいくつかありました。具体的な例を挙げるとReact Native 0.43(2017年4月リリース)からReact Native 0.49(2017年10月リリース)へのアップグレード作業では、前者がReact 16のα版、後者がβ版を利用していた関係でほぼ不可能とも思える作業になりました。多くのReactライブラリがWebを想定して設計されているため、最新版のReactへの対応がなされておらず手こずることとなりました。2017年中頃のインフラチームはこの依存解決の問題に追われ、結果的に多くのコストが費やされたこととなります。 130 | 131 | ### アクセシビリティ 132 | 2017年に私たちはアクセシビリティに関する[大幅な改修](https://airbnb.design/designing-for-access/)を行い、ハンディキャップを抱えた人たちが最適なリスティングを見つけ、予約できるように努力しました。しかしながらReact NativeのアクセシビリティAPIにはいくつもの穴があります。最低限のアクセシビリティ要件を満たすためだけでも、私たちは[Forkした](https://github.com/airbnb/react-native/commits/0.46-canary)React Nativeをメンテナンスして修正をマージする必要がありました。AndroidやiOSならば1行加えるだけですむような修正でも、React Nativeでの実装方法を考え、変更を加え、React Native Coreに修正を出してケアするのには膨大な時間がかかりました。 133 | 134 | ### やっかいなクラッシュ 135 | 私たちはいくつかの修正が難しい奇妙な問題にもぶつかりました。例をあげると[こちら](https://issuetracker.google.com/issues/37045084)の@ReactPropに関する問題を現在も調査中で、同じ端末同じソフトウェア上であっても問題を再現・究明できずにいます。 136 | 137 | ### Androidでのプロセスの永続化 138 | Androidは頻繁にバックグラウンドプロセスをリフレッシュしますが、その対策としてアプリケーションバンドルに[stateを同期的に保存](https://developer.android.com/topic/libraries/architecture/saving-states#use_onsaveinstancestate_as_backup_to_handle_system_initiated_process_death)することが可能です。しかしながらReact Nativeにおいては全てのstateに対してJSスレッドからしかアクセスできないため、これを同期的に行うことができません。もしできたとしてもReduxにはシリアライズ可能なデータと不可能なデータが混在していますし、savedInstanceStateの容量では足りない大きさのデータも含まれるため、どちらにせよプロダクションで[クラッシュ](https://medium.com/@mdmasudparvez/android-os-transactiontoolargeexception-on-nougat-solved-3b6e30597345)してしまいます。 139 | 140 | 141 | # その他の記事 142 | - [Part 1](https://medium.com/airbnb-engineering/react-native-at-airbnb-f95aa460be1c)([日本語訳](https://github.com/react-native-jp/react-native-at-airbnb-jp-translation/blob/master/1-alt-react-native-at-airbnb.md)): React Native at Airbnb 143 | - [Part 2](https://medium.com/airbnb-engineering/react-native-at-airbnb-the-technology-dafd0b43838)([日本語訳](https://github.com/react-native-jp/react-native-at-airbnb-jp-translation/blob/master/2-react-native-at-airbnb-the-technology.md)): The Technology(本記事) 144 | - [Part 3](https://medium.com/airbnb-engineering/building-a-cross-platform-mobile-team-3e1837b40a88)([日本語訳](https://github.com/react-native-jp/react-native-at-airbnb-jp-translation/blob/master/3-building-a-cross-platform-mobile-team.md)): Building a Cross-Platform Mobile Team 145 | - [Part 4](https://medium.com/airbnb-engineering/sunsetting-react-native-1868ba28e30a)([日本語訳](https://github.com/react-native-jp/react-native-at-airbnb-jp-translation/blob/master/4-sunsetting-react-native.md)): Making a Decision on React Native 146 | - [Part 5](https://medium.com/airbnb-engineering/whats-next-for-mobile-at-airbnb-5e71618576ab)([日本語訳](https://github.com/react-native-jp/react-native-at-airbnb-jp-translation/blob/master/5-what%E2%80%99s-next-for-mobile-at-airbnb.md)): What’s Next for Mobile 147 | -------------------------------------------------------------------------------- /3-building-a-cross-platform-mobile-team.md: -------------------------------------------------------------------------------- 1 | > 本記事はReact Native at Airbnbのpart3となります。数えきれない程の技術的なメリットとデメリットに加え、私達はエンジニアリング組織にとってReact Nativeが何を意味しているかという事を学びました。React Nativeを適用するという事は新しいライブラリや設計パターンを既存のプラットフォームに導入する事よりもはるかに複雑です。React Nativeの導入は沢山の組織的なチャレンジを私達にもたらしました。殆どのケースで最終的に解決されたり避ける事のできる技術的なチャレンジとは異なり組織的なチャレンジはより認識、改善していく事が難しい問題です。幸いな事に私達のモバイル開発文化は健全ですが、React Nativeの導入に辺り意識すべき沢山のポイントが存在します。 2 | 3 | ### React Native に対する様々な反応 4 | 5 | 私達の経験では、React Nativeに対するエンジニアの反応は実に様々でした。iOS/Android/Webを統一する銀の弾丸だと褒め称える者もいれば、React Nativeの利用をチーム内で全く認めないような者までいました。同じ状況はReact Nativeの利用を開始してからも起こったのです。幾つかのチームは素晴らしい体験を得た一方で導入を後悔しNativeに戻っていったチームもいました。 6 | 7 | ## 根本原因の特定 8 | 9 | React Nativeで開発をしていて、避けることのできないバグや改善、パフォーマンスの問題に遭遇しました。しかしながら、沢山の流動的なポイントが存在しました。 10 | 11 | - React Native自体の開発は活発です 12 | - 私達は機能開発とインフラストラクチャの整備を同時に進めていました 13 | - 殆どのエンジニアにとってReact Nativeを学ぶ事は比較的新しい事でした 14 | - 私達のdev/production環境でのデバッグに関するドキュメントやガイダンスは一貫性に欠き、紛らわしいものでした 15 | 16 | 結果として、問題の根本的な原因を特定する事が困難な事態にしばしば遭遇しました。どのチームが問題の原因なのかはたまたReact Native固有の問題なのかが明確でないケースがしばしばありました。 17 | 18 | ### React NativeはNative 19 | 20 | よくある思い違いはReact NativeがあればNativeコードを一切書かなくても良いという思い込みです。しかしながら、現時点ではそれは幻想といってもいいです。React NativeのNativeの部分は依然としてしばしば私達の前に姿を現します。例えば、Textは各プラットフォームによって若干異なる表示の仕方になります。キーボードも異なる挙動をし、AndroidではActivityは画面回転時に再構築されます。React Nativeを用いて高品質な体験を提供するには両OSの世界への注意深い配慮が必要です。3プラットフォームのノウハウをバランスよく取り入れないといけないという問題は一貫性のある高品質な体験の提供を難しくします。 21 | 22 | ### プラットフォームを横断したデバッグ 23 | 24 | 殆どのエンジニアはせいぜい1つか2つのプラットフォームにしか精通していません。Android、iOS、Reactの全部について詳しい人に出会えるのはごく稀です。React Native上での殆どの開発がReactやJavaScriptによって成されるとしても、Nativeのビルドやデバッグの知識を求められる事は存在します。その状況ではエンジニアは時として自身の専門外の状況でデバッグをしなければなりません。この状況はエンジニアが問題を解決する為にどこから手を付けていいか自信がない時にさらにひどくなります。 25 | 26 | ### 採用 27 | 28 | 私達はReact Nativeに対して投資をしてきましたが、私達のモバイルチームと野望はそれと並行して加速していきました。しかしながら、コミュニティの噂を通して多くの人はAirbnbとReact Nativeを関連付けて考え、一部の人は私達のアプリが100%React Nativeであると信じていました。それは真実とは程遠いですが、多くのiOS/Androidエンジニアは結果としてAirbnbに応募する事を躊躇う事になりました。もしあなたがその一部だとしたら、私達は積極採用中ですよ! 29 | 30 | ### ハイブリッドアプリは難しい 31 | 32 | 100% Nativeか、100% React Nativeかという世界は比較的単純です。しかしながら、一度コードを混ぜてしまうと沢山の新しい問題が噴出します。どうやってチームを分割しようか?どうやってチーム同士は協業するのか?どうやって状態をアプリ間で共有する?どうやってテストする?どうやってエンジニアは3つのプラットフォームを跨いでデバッグする?どうやって新機能をReactかNativeで開発するか決める?どうやって組織を跨いでエンジニアを採用/配属する?これらの看過できない問題はあなたがハイブリッド開発の道を行くときには必ず生じますよ。 33 | 34 | ### 3つの開発環境 35 | 36 | 強いReact Nativeエンジニアになる為には、React Native、Android、iOSの環境に関して精通してキャッチアップしなければなりません。Airbnbと同じサイズの組織であればそれぞれのプラットフォームの環境のセットアップ、学習コストやキャッチアップにはかなりの時間がかかります。数週間の休暇から戻ってくると何時間も全ての情報のキャッチアップに費やす事になります。 37 | 38 | ### NativeとReact Nativeのバランス 39 | 40 | 問題に対する最適な答えがNativeとReact Nativeの両方に跨っている、というケースは数多く存在します。例えば私達のNavigationライブラリはActivityとViewControllerを主に利用しておりコードはほとんどNativeです。殆どの場合で、コードがNativeで書かれるかReact Nativeで書かれるべきかというのは自明ではなく当然の事として、エンジニアは自分が慣れ親しんだプラットフォームでコードを書き、そのコードは理想的とは言えないケースがしばしば起こります。 41 | 42 | ### クロスプラットフォームのテスト 43 | 44 | エンジニアはまず1つのプラットフォーム上で開発を進めがちです。勿論もう一方のプラットフォームでの動作を保証し、テストをしなければならずそれは殆どの場合React Nativeの力でなんとかなるのですが、然しながらそれらの検証が不十分なままQAやプロダクション環境で問題を起こしてしまった事もしばしばありました。 45 | 46 | ### チーム分割 47 | 48 | NativeとReact Nativeで開発を進めているチームはしばしば技術とコミュニケーション両方の問題にぶつかります。NativeとReact Nativeのコードを分割してしまえば、コードの断片化が発生します。ロジック、モデル、状態の共通化はよりチャレンジングになりエンジニアは全体のフローを一貫して受け持つ事になり、彼らの得意分野の力を出せなくなります。私達はこれらの問題は最初は起こるがWebチームとの協働により徐々にましになっていくだろうと期待していました。が、実際には幾つかのチームがコードや知識のシェアをWeb-Mobile間で始めただけで殆どのチームは潜在的な利益に気づかないままでした。 49 | 50 | ### (開発者にとっての) イテレーションのスピード 51 | 52 | 私達のゴールの1つは開発のスピードを高速化する事でした。殆どの場合、React Nativeの機能は各プラットフォームに担当をアサインする代わりに一人のエンジニアによって書かれます。React Nativeエンジニアの観点から見れば、AndroidかiOSどちらかにかかる時間より50%以上の時間がかかれば、全体で数時間の短縮になったとしても開発者にとってはそれは実に長く感じられます。 53 | 54 | ### 公式リソースとドキュメント 55 | 56 | iOS/Androidは10年の歴史と何百万の開発者を抱えており大量の学習教材、OSS、オンラインの情報が存在します。私達はCodePathや沢山の情報をNativeエンジニアの育成の為に利用してきました。React Nativeはクロスプラットフォーム開発の一角を占めるようになりましたが、それでもAndroidやiOSのコミュニティよりは小さいです。殆どのインフラストラクチャを自前で開発しないといけなかったという事実は私達がReact Nativeの教育や育成に投資をしすぎたという事を意味しています。 57 | 58 | # その他の記事 59 | - [Part 1](https://medium.com/airbnb-engineering/react-native-at-airbnb-f95aa460be1c)([日本語訳](https://github.com/react-native-jp/react-native-at-airbnb-jp-translation/blob/master/1-alt-react-native-at-airbnb.md)): React Native at Airbnb 60 | - [Part 2](https://medium.com/airbnb-engineering/react-native-at-airbnb-the-technology-dafd0b43838)([日本語訳](https://github.com/react-native-jp/react-native-at-airbnb-jp-translation/blob/master/2-react-native-at-airbnb-the-technology.md)): The Technology 61 | - [Part 3](https://medium.com/airbnb-engineering/building-a-cross-platform-mobile-team-3e1837b40a88)([日本語訳](https://github.com/react-native-jp/react-native-at-airbnb-jp-translation/blob/master/3-building-a-cross-platform-mobile-team.md)): Building a Cross-Platform Mobile Team(本記事) 62 | - [Part 4](https://medium.com/airbnb-engineering/sunsetting-react-native-1868ba28e30a)([日本語訳](https://github.com/react-native-jp/react-native-at-airbnb-jp-translation/blob/master/4-sunsetting-react-native.md)): Making a Decision on React Native 63 | - [Part 5](https://medium.com/airbnb-engineering/whats-next-for-mobile-at-airbnb-5e71618576ab)([日本語訳](https://github.com/react-native-jp/react-native-at-airbnb-jp-translation/blob/master/5-what%E2%80%99s-next-for-mobile-at-airbnb.md)): What’s Next for Mobile 64 | -------------------------------------------------------------------------------- /4-sunsetting-react-native.md: -------------------------------------------------------------------------------- 1 | この記事はAirbnb社におけるReact Native体験と `次の時代`のモバイルアプリケーション開発について記したブログシリーズの第四弾です。 2 | 3 | これまで多くのチームがReact Nativeを信頼して今後も利用し続ける計画を立てていましたが、結論としてReact Nativeが私たちのゴールを達成することはできませんでした。継続してReact Nativeに投資を続けるための数多くの[技術的な問題](https://medium.com/airbnb-engineering/react-native-at-airbnb-the-technology-dafd0b43838)や[組織構造の問題](https://medium.com/airbnb-engineering/building-a-cross-platform-mobile-team-3e1837b40a88)に対して、私たちは解決策を見出せなかったのです。 4 | 5 | この経験を活かして前に進むため、AirbnbではReact Nativeから漸次的に退いて全ての力をネイティブに再投資します。 6 | 7 | ## 目標達成の失敗 8 | ### より早く動くこと 9 | React Nativeが期待通りのパフォーマンスを発揮していた頃、エンジニアたちはかつてないスピードで開発を進めることができました。しかしこの一連の記事で触れている[技術的な問題](https://medium.com/airbnb-engineering/react-native-at-airbnb-the-technology-dafd0b43838)や[組織構造の問題](https://medium.com/airbnb-engineering/building-a-cross-platform-mobile-team-3e1837b40a88)によってフラストレーションが蓄積され、予見できなかった様々な遅延が多くのプロジェクトにおいて発生しました。 10 | 11 | ### 品質を保つこと 12 | React Native自体の成熟度が上がったことや、私たちの中でより多くの知見が蓄積されたことなどで、近頃はかつて実現可能性すら分からなかった多くのことが可能になりました。Shared Element TransitionsやParallaxを作ったり、フレームレートの低下が頻繁に起きていた画面のパフォーマンスを劇的に向上させたりといったことです。しかしながら初期化処理や非同期なファーストビューの描画に関するものなどの[様々な技術的チャレンジ](https://medium.com/airbnb-engineering/react-native-at-airbnb-the-technology-dafd0b43838)によって叶わなかったものがあるのも事実です。社の内外におけるリソースの不足により、これらの問題は一層難しくなりました。 13 | 14 | ### Write Code Once Instead of Twice 15 | 私たちのアプリにおいてはReact Nativeの大部分が複数のプラットフォームで共有されているものの、そもそもReact Nativeが使われているのはアプリ全体のわずかな部分でしかありません。更に、プロダクトエンジニアの生産性を担保するためには大量のbridgingが必要になります。その結果として私たちは(2つではなく)3つ全てのプラットフォームに対する統合的な補助コードを作ることになりました。私たちはWebとネイティブにおけるコードシェアリングの可能性を信じ、実際にいくつかのNPMパッケージを共有することができましたが、それを除けば本当に意味のある"Write Code Once Instead of Twice"は実現しませんでした。 16 | 17 | ## 撤退計画 18 | 上記のようにReact Nativeは私たちが定めたゴールを達成することができなかったため、私たちに適した道具ではないということを結論づけました。目下、複数のチームと力を合わせて最適な移行プランを計画中です。既にReact Nativeを利用した全ての機能開発は取りやめ、高いトラフィックを持つ画面については年内を目標に大部分をネイティブに置き換え予定です。これらは必ずしもReact Nativeのみに責任があるわけではなく、予てより予定されていたスケジュール変更の影響もあります。私たちのネイティブインフラチームも2018年中はReact Nativeのサポートを行う予定です。2019年からは徐々にサポートを減少させ、起動時のランタイム初期化等のReact Nativeがオーバーヘッドする部分も削減してく予定です。 19 | 20 | Airbnb社は、オープンソースの力と意義を信じています。私たちは積極的にOSSを利用するだけでなく、世界中の多くのプロジェクトにコントリビュートしており、React Nativeに関するものも公開してきました。社全体として徐々にReact Nativeから離れていくなかでReact Nativeレポジトリに対して十分なメンテナンスが行えなくなってしまいますが、コミュニティにとってのベストを考えていくつかのプロジェクトを[React Native Community](https://github.com/react-native-community)に移譲します。既に[react-native-maps](https://github.com/react-community/react-native-maps)については取り組みが始まっており、[native-navigation](https://github.com/airbnb/native-navigation)や[lottie-react-native](https://github.com/airbnb/lottie-react-native/)についても対応予定です。 21 | 22 | ## そんなに悪くなかったよ? 23 | 私たちのゴールを達成することこそ叶いませんでしたが、React Nativeに触れていたエンジニア達は概ね肯定的な意見です。内訳をみると、 24 | 25 | - 60%が「素晴らしい開発経験だった」と感じた 26 | - 20%がやや肯定的 27 | - 15%がやや否定的 28 | - 5%が強く否定 29 | 30 | となっています。また63%のエンジニアがまたチャンスがあればReact Nativeを選択すると答え、74%が新しいプロジェクトにおいて選択肢に含めると答えました。注目すべき点は、これらの調査対象が全て一度はReact Nativeを使っていたエンジニアであるということです。 31 | 32 | 彼らは80,000行ものプロダクトコードを産み出し、220もの画面を作り、40,000行ものJavaScriptのインフラストラクチャを書いたエンジニアです。参考のために触れておくと、私たちはネイティブにおいてはこの10倍ものコードと4倍もの数の画面をそれぞれのプラットフォームで開発しています。 33 | 34 | ## React Nativeは成熟してきている 35 | この一連のポストは今日の時点における私たちのReact Native体験を振り返るものです。ですがFacebookやReact Native CommunityのメンバーはRNがハイブリッドアプリでもスケールするよう身を砕いています。かつてないスピードでReact Nativeは発展しているのです。昨年には2,500ものコミットが反映され、Facebook自身も私たちが直面したような問題を真摯に[受け止めて](https://facebook.github.io/react-native/blog/2018/06/14/state-of-react-native-2018)います。私たちがこれ以上React Nativeに投資することはありませんが、これからの開発を見守れることを楽しみにしています。なぜならReact Nativeの成功は私たちのプロダクトを使ってくれる世界中の人々の幸せにつながるのですから。 36 | 37 | ## 学び 38 | 私たちは急速に発展を続けるアプリケーションにReact Nativeを組み込みました。その中で直面した問題の多くは、私たちがハイブリッドモデルのアプローチを選択したことに由来します。しかし小さな会社では十分なリソースが無く、このスケールの会社だったからこそ得られたことや解決した問題もあるでしょう。React Nativeをネイティブとシームレスに統合することは可能です。ですが難しいことです。React Nativeを使う全ての会社が、そのチームの構成や、既存のアプリや、プロダクトの要求や、React Nativeの成熟度によってユニークな経験をするのだろうと思います。 39 | 40 | 全てのピースがはまった時(そういう場面はたくさんありました)、React Nativeは開発のイテレーションスピードや品質、そして開発体験全体において私たちの期待通りもしくは期待以上のパフォーマンスを発揮してくれました。そういう時には、私たちはモバイル開発自体を変革させる瀬戸際に立っているのだというような気持ちになりました。もちろんそのような素晴らしい体験も是非していただきたいですが、改めてその恩恵と痛み、そして今の優先事項やエンジニアリング組織のリソースを比較したとき、それは私たちにふさわしいものではないと結論づけました。 41 | 42 | 新たなプラットフォームの採用はとても大きな決断で、あなたのチームが抱える様々なユニークなファクターによって決まります。私たちが経験したことやReact Nativeを手放すことになった理由は、あなたのチームには当てはまらないかもしれません。実際に[たくさんの会社](https://medium.com/@Pinterest_Engineering/supporting-react-native-at-pinterest-f8c2233f90e6)がReact Nativeによる素晴らしい体験を継続しており、多くの人々にとってはいまだにベストなツールかもしれません。 43 | 44 | 私たちはこれまでもネイティブに投資をし続けていましたが、React Nativeから離れることでかつてないほどのリソースをより良いアプリを作ることに投下できます。次の記事で私たちの新たなネイティブに関する取り組みを知ってください! 45 | 46 | 47 | # その他の記事 48 | - [Part 1](https://medium.com/airbnb-engineering/react-native-at-airbnb-f95aa460be1c)([日本語訳](https://github.com/react-native-jp/react-native-at-airbnb-jp-translation/blob/master/1-alt-react-native-at-airbnb.md)): React Native at Airbnb 49 | - [Part 2](https://medium.com/airbnb-engineering/react-native-at-airbnb-the-technology-dafd0b43838)([日本語訳](https://github.com/react-native-jp/react-native-at-airbnb-jp-translation/blob/master/2-react-native-at-airbnb-the-technology.md)): The Technology 50 | - [Part 3](https://medium.com/airbnb-engineering/building-a-cross-platform-mobile-team-3e1837b40a88)([日本語訳](https://github.com/react-native-jp/react-native-at-airbnb-jp-translation/blob/master/3-building-a-cross-platform-mobile-team.md)): Building a Cross-Platform Mobile Team 51 | - [Part 4](https://medium.com/airbnb-engineering/sunsetting-react-native-1868ba28e30a)([日本語訳](https://github.com/react-native-jp/react-native-at-airbnb-jp-translation/blob/master/4-sunsetting-react-native.md)): Making a Decision on React Native(本記事) 52 | - [Part 5](https://medium.com/airbnb-engineering/whats-next-for-mobile-at-airbnb-5e71618576ab)([日本語訳](https://github.com/react-native-jp/react-native-at-airbnb-jp-translation/blob/master/5-what%E2%80%99s-next-for-mobile-at-airbnb.md)): What’s Next for Mobile 53 | -------------------------------------------------------------------------------- /5-what’s-next-for-mobile-at-airbnb.md: -------------------------------------------------------------------------------- 1 | # [What’s Next for Mobile at Airbnb](https://medium.com/airbnb-engineering/whats-next-for-mobile-at-airbnb-5e71618576ab) 2 | 3 | ### Exciting Times Ahead 4 | 5 | React Nativeに挑戦している間も、我々はNative側での努力も怠ること無く継続していました。今日ではいくつものエキサイティングな、プロダクトに導入済の(あるいはもうすぐ導入される)プロジェクトが存在しています。そのうち幾つかのプロジェクトはReact Nativeの良い部分や我々の経験を元に開発されています。 6 | 7 | #### Server-Driven Rendering 8 | 9 | React Nativeを使っていないとしても、私達はプロダクトコードを"一度だけ"書くことに価値を見出しています。私達はDLS(Airbnbの社内デザイン言語)を多用しており多くの画面においてAndroidとiOSでほぼ同じデザインを適用しています。 10 | 11 | 幾つかのチームで実験を行い、パワフルなサーバドリブンのレンダリングフレームワークを統一する事を開始しました。このフレームワークにより、サーバーはデバイスに描画すべきコンポーネント、スクリーン設定、発火するアクションを記述したデータを送信し、各プラットフォームはデータを解釈しnativeの画面を描画したりDLSを用いた全体のフローを描画します。 12 | 13 | 大規模なサーバードリブンレンダリングは幾つかのチャレンジとセットになっています。我々が解決しようとしている一部を紹介すると: 14 | 15 | - 後方互換性を維持したまま安全にコンポーネント定義をアップデートする 16 | - プラットフォームを跨いで型定義を共有する 17 | - 実行時のイベントに応答する(ボタンのタップやユーザーインプットなど) 18 | - JSONドリブンなスクリーンの遷移を内部状態を保持しながら行う 19 | - ビルド時に存在しないカスタムコンポーネントを描画する 20 | 我々は[Lona](https://github.com/airbnb/Lona/)というformatを用いてこれを実験しています 21 | 22 | サーバードリブンレンダリングフレームワークは機能をOTAで変更したりテストしたりすることができるという意味で既に我々に大きな価値をもたらしています。 23 | 24 | ### Epoxy Components 25 | 26 | 2016年に、我々は[Epoxy](https://github.com/airbnb/epoxy)をAndroid向けにオープンソース化しました。 27 | Epoxyは多様なcellを持つRecyclerViews, UICollectionViews, UITableViewsを可能にするフレームワークで、殆どの新しい画面にはEpoxyを利用しています。Epoxyを利用する事でそれぞれのスクリーンを独立したcomponentとして定義する事が可能になり、遅延初期化も実施する事ができます。今日では私達はiOS/Androidの両方のEpoxy実装を公開しています。 28 | 29 | iOSではコードは以下の様な形となります。 30 | 31 | ```swift 32 | BasicRow.epoxyModel( 33 | content: BasicRow.Content( 34 | titleText: "Settings", 35 | subtitleText: "Optional subtitle"), 36 | style: .standard, 37 | dataID: "settings", 38 | selectionHandler: { [weak self] _, _, _ in 39 | self?.navigate(to: .settings) 40 | }) 41 | ``` 42 | 43 | Androidでは、KotlinのDSLの機能を利用し型安全に簡潔にコンポーネントを実装できます。 44 | 45 | ```kotlin 46 | basicRow { 47 | id("settings") 48 | title(R.string.settings) 49 | subtitleText(R.string.settings_subtitle) 50 | onClickListener { navigateTo(SETTINGS) } 51 | ``` 52 | 53 | ### Epoxy Diffing 54 | 55 | Reactでは、renderメソッドはコンポーネントのリストをreturnします。Reactのパフォーマンスの肝はそれらのコンポーネントは単に描画したいViewやHTMLのモデルとして表現できるという事です。コンポーネントのツリーはdiffが計算され必要な変更のみが実施されます。我々はEpoxyにおいて似たようなコンセプトを導入しました。EpoxyではbuildModelsメソッドの中にスクリーン全体の(を表現する)モデルを宣言します。Kotlinの優雅なDSLで表現されるその実装はReactとコンセプト的にとても似ており以下の様になります。 56 | 57 | ```kotlin 58 | override fun EpoxyController.buildModels() { 59 | header { 60 | id("marquee") 61 | title(R.string.edit_profile) 62 | } 63 | inputRow { 64 | id("first name") 65 | title(R.string.first_name) 66 | text(firstName) 67 | onChange { 68 | firstName = it 69 | requestModelBuild() 70 | } 71 | } 72 | // Put the rest of your models here... 73 | } 74 | ``` 75 | 76 | データが変更されると、`requestModelBuild()`が呼び出されRecyclerViewのメソッドが最適な形で呼び出され画面が再描画されます。 77 | 78 | iOSではコードは以下の様になります。 79 | 80 | ```swift 81 | override func itemModel(forDataID dataID: DemoDataID) -> EpoxyableModel? { 82 | switch dataID { 83 | case .header: 84 | return DocumentMarquee.epoxyModel( 85 | content: DocumentMarquee.Content(titleText: "Edit Profile"), 86 | style: .standard, 87 | dataID: DemoDataID.header) 88 | case .inputRow: 89 | return InputRow.epoxyModel( 90 | content: InputRow.Content( 91 | titleText: "First name", 92 | inputText: firstName) 93 | style: .standard, 94 | dataID: DemoDataID.inputRow, 95 | behaviorSetter: { [weak self] view, content, dataID in 96 | view.textDidChangeBlock = { _, inputText in 97 | self?.firstName = inputText 98 | self?.rebuildItemModel(forDataID: .inputRow) 99 | } 100 | }) 101 | } 102 | } 103 | ``` 104 | 105 | ### A New Android Product Framework (MvRx) 106 | 107 | 最近最もエキサイティングな開発の一つは私達が内部で開発を進めているMvRxと呼ばれるフレームワークです。MvRxはEpoxy、Jetpack、RxJava、KotlinとReactから得た多くの原則を組み合わせ新しい画面の構築を今までにないほどより簡単にシームレスにします。これはReactのベストプラクティスと我々が発見した共通の実装パターンから生み出された独自のフレキシブルフレームワークです。MvRxはスレッドセーフでありほとんどの処理はメインスレッド外で動作する為スクロールやアニメーションは非常にスムーズに動作します。 108 | 109 | これまでの所、MvRxは多くのスクリーンで動作しライフサイクルと付き合う必要性を殆ど取り除いてきました。私達はいくつかのAndroidプロダクトでMvRxを試しておりうまくいくようであればOSS化する事を計画しています。以下はネットワークリクエストを必要とする画面を構築する為のコードです。 110 | 111 | ```kotlin 112 | data class SimpleDemoState(val listing: Async = Uninitialized) 113 | 114 | class SimpleDemoViewModel(override val initialState: SimpleDemoState) : MvRxViewModel() { 115 | init { 116 | fetchListing() 117 | } 118 | 119 | private fun fetchListing() { 120 | // This automatically fires off a request and maps its response to Async121 | // which is a sealed class and can be: Unitialized, Loading, Success, and Fail. 122 | // No need for separate success and failure handlers! 123 | // This request is also lifecycle-aware. It will survive configuration changes and 124 | // will never be delivered after onStop. 125 | ListingRequest.forListingId(12345L).execute { copy(listing = it) } 126 | } 127 | } 128 | 129 | class SimpleDemoFragment : MvRxFragment() { 130 | // This will automatically subscribe to the ViewModel state and rebuild the epoxy models 131 | // any time anything changes. Similar to how React's render method runs for every change of 132 | // props or state. 133 | private val viewModel by fragmentViewModel(SimpleDemoViewModel::class) 134 | 135 | override fun EpoxyController.buildModels() { 136 | val (state) = withState(viewModel) 137 | if (state.listing is Loading) { 138 | loader() 139 | return 140 | } 141 | // These Epoxy models are not the views themself so calling buildModels is cheap. RecyclerView 142 | // diffing will be automaticaly done and only the models that changed will re-render. 143 | documentMarquee { 144 | title(state.listing().name) 145 | } 146 | // Put the rest of your Epoxy models here... 147 | } 148 | 149 | override fun EpoxyController.buildFooter() = fixedActionFooter { 150 | val (state) = withState(viewModel) 151 | buttonLoading(state is Loading) 152 | buttonText(state.listing().price) 153 | buttonOnClickListener { _ -> } 154 | } 155 | } 156 | ``` 157 | 158 | MvRxはFragmentの引数の処理、プロセスを跨いだsavedInstanceStateによる永続化、TTIのトラッキングなどに関してシンプルな概念を持っており他にも多くの機能があります。 159 | 160 | iOSでもまだβテストの段階ですが似たフレームワークを開発しています。 161 | 162 | これらについて近々さらに情報を公開する予定ですが、これまで積み上げてきた成果に我々はとても興奮しています。 163 | 164 | ### Iteration Speed 165 | 166 | React Nativeから移行してきて明らかな問題の一つが開発サイクルのスピードです。1,2秒で変更をテストできる世界から15分も待たないといけない世界へ戻ってくるのは厳しいですよね。幸運な事に、我々はこちらに関しても殆ど必要とされている支援を提供する事ができました。 167 | 168 | 私達はAndroidとiOSでアプリの一部のみをコンパイルし、特定のモジュールに依存する(launcherを含む部分的な)アプリを生成するような基盤を構築しています。 169 | 170 | Androidでは、Gradleのプロダクトフレーバーを利用して実現しています。gradleモジュールは以下の様になります。 171 | 172 | ![](https://cdn-images-1.medium.com/max/1600/1*KVrbsdwESyfbtKFeh2acXg.png) 173 | 174 | この新しい依存関係の指定はエンジニアにアプリを部分的にビルドする事を可能にします。IntelliJの[module unloading](https://blog.jetbrains.com/idea/2017/06/intellij-idea-2017-2-eap-introduces-unloaded-modules/)という機能と合わせる事でMac book Pro上で劇的にビルドとIDEのパフォーマンスが改善しました。 175 | 176 | 私達は新しいテスト用フレーバーを生成するスクリプトを開発し数ヶ月の間に20以上のフレーバーを作成してきました。新しいフレーバーを利用した開発速度は平均2.5倍高速化し5分以上かかっていたビルド時間は15倍改善しました。 177 | 178 | 参考までに、[こちら](https://gist.github.com/gpeal/d68e4fc1357ef9d126f25afd9ab4eee2)が動的に(root moduleへの参照を持つ)プロダクトフレーバーを生成するスニペットです。 179 | 180 | 似たようにiOSではmoduleは以下の様になります。 181 | 182 | ![](https://cdn-images-1.medium.com/max/1600/1*AVB7em_JCmj-JmjTCkLdQw.png) 183 | 184 | 同じシステムでビルドは3~8倍高速化しました。 185 | 186 | ### Conclusion 187 | 188 | 会社にとって、新しい技術に挑戦する事を恐れず、高い品質、開発速度、開発者体験を維持する事はとても重要です。結論としては、React Nativeは機能をリリースし、モバイル開発にとって新しい考え方を私達にもたらす必要なツールでした。もしこの話を聞いてあなたも参加してみたいと思ったならば、ぜひ私達までご一報を! 189 | 190 | # その他の記事 191 | - [Part 1](https://medium.com/airbnb-engineering/react-native-at-airbnb-f95aa460be1c)([日本語訳](https://github.com/react-native-jp/react-native-at-airbnb-jp-translation/blob/master/1-alt-react-native-at-airbnb.md)): React Native at Airbnb 192 | - [Part 2](https://medium.com/airbnb-engineering/react-native-at-airbnb-the-technology-dafd0b43838)([日本語訳](https://github.com/react-native-jp/react-native-at-airbnb-jp-translation/blob/master/2-react-native-at-airbnb-the-technology.md)): The Technology 193 | - [Part 3](https://medium.com/airbnb-engineering/building-a-cross-platform-mobile-team-3e1837b40a88)([日本語訳](https://github.com/react-native-jp/react-native-at-airbnb-jp-translation/blob/master/3-building-a-cross-platform-mobile-team.md)): Building a Cross-Platform Mobile Team 194 | - [Part 4](https://medium.com/airbnb-engineering/sunsetting-react-native-1868ba28e30a)([日本語訳](https://github.com/react-native-jp/react-native-at-airbnb-jp-translation/blob/master/4-sunsetting-react-native.md)): Making a Decision on React Native 195 | - [Part 5](https://medium.com/airbnb-engineering/whats-next-for-mobile-at-airbnb-5e71618576ab)([日本語訳](https://github.com/react-native-jp/react-native-at-airbnb-jp-translation/blob/master/5-what%E2%80%99s-next-for-mobile-at-airbnb.md)): What’s Next for Mobile(本記事) 196 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # [翻訳]React Native at Airbnb 2 | 3 | [React Native at Airbnb](https://medium.com/airbnb-engineering/react-native-at-airbnb-f95aa460be1c)の日本語訳を管理するリポジトリです。 4 | 5 | - part1: [React Native at Airbnb](https://medium.com/airbnb-engineering/react-native-at-airbnb-f95aa460be1c)/[日本語訳](https://github.com/react-native-jp/react-native-at-airbnb-jp-translation/blob/master/1-alt-react-native-at-airbnb.md) 6 | - part2: [React Native at Airbnb: The Technology](https://medium.com/airbnb-engineering/react-native-at-airbnb-the-technology-dafd0b43838) 7 | /[日本語訳](https://github.com/react-native-jp/react-native-at-airbnb-jp-translation/blob/master/2-react-native-at-airbnb-the-technology.md) 8 | - part3: [Building a Cross-Platform Mobile Team](https://medium.com/airbnb-engineering/building-a-cross-platform-mobile-team-3e1837b40a88)/[日本語訳](https://github.com/react-native-jp/react-native-at-airbnb-jp-translation/blob/master/3-building-a-cross-platform-mobile-team.md) 9 | - part4: [Sunsetting React Native](https://medium.com/airbnb-engineering/sunsetting-react-native-1868ba28e30a)/[日本語訳](https://github.com/react-native-jp/react-native-at-airbnb-jp-translation/blob/master/4-sunsetting-react-native.md) 10 | - part5: [What’s Next for Mobile at Airbnb](https://medium.com/airbnb-engineering/whats-next-for-mobile-at-airbnb-5e71618576ab)/[日本語訳](https://github.com/react-native-jp/react-native-at-airbnb-jp-translation/blob/master/5-what%E2%80%99s-next-for-mobile-at-airbnb.md) 11 | 12 | 翻訳の修正や問題はissueもしくはPRでお願い致します。 13 | 14 | --------------------------------------------------------------------------------