$30 off During Our Annual Pro Sale. View Details »

じゃらんnetアプリ Flutterリプレイスの道のり/クロスプラットフォーム開発2022 -...

Recruit
July 28, 2022

じゃらんnetアプリ Flutterリプレイスの道のり/クロスプラットフォーム開発2022 -Flutter・React Nativeの導入と実践-

2022/07/27 CROOZ.inc(クルーズ株式会社)主催「クロスプラットフォーム開発2022 -Flutter・React Nativeの導入と実践-」での、桐山の講演資料になります。

Recruit

July 28, 2022
Tweet

More Decks by Recruit

Other Decks in Technology

Transcript

  1. 「じゃらんnetアプリのFlutterリプレイス」について
 • じゃらんnetアプリは総コード量80万行に及ぶ大規模なアプリ 
 • 我々のチームは様々な試行錯誤を行いながらリプレイスを推進している 
 
 • どの様な進め方/考え方でFlutterリプレイスしているのか

    
 • これまでを振り返りどの様にリプレイスを進めると良さそうか 
 →リプレイスの過程で得られた知見をお伝えする 
 
 なお本発表は同僚/チームメンバーと一緒に取り組んできた内容を自分が代表して発表します。 
 話すこと
 3

  2. 1. じゃらんnetのご紹介
 
 2. じゃらんnetアプリをFlutterリプレイスしている背景
 
 3. じゃらんnet Flutterリプレイスの道のり
 a.

    Add-to-appを使用したFlutterの部分的導入
 b. じゃらん全体のFlutter化を見据えた構成変更
 c. ネイティブコードの段階的なFlutterへの置き換え
 
 4. これまでの道のりの振り返り
 説明の流れ
 4

  3. 1. じゃらんnetのご紹介
 
 2. じゃらんnetアプリをFlutterリプレイスしている背景
 
 3. じゃらんnet Flutterリプレイスの道のり
 a.

    Add-to-appを使用したFlutterの部分的導入
 b. じゃらん全体のFlutter化を見据えた構成変更
 c. ネイティブコードの段階的なFlutterへの置き換え
 
 4. これまでの道のりの振り返り
 説明の流れ
 5

  4. 1. じゃらんnetのご紹介
 
 2. じゃらんnetアプリをFlutterリプレイスしている背景
 
 3. じゃらんnet Flutterリプレイスの道のり
 a.

    Add-to-appを使用したFlutterの部分的導入
 b. じゃらん全体のFlutter化を見据えた構成変更
 c. ネイティブコードの段階的なFlutterへの置き換え
 
 4. これまでの道のりの振り返り
 説明の流れ
 8

  5. じゃらんnetアプリのリプレイス検討
 • クロスプラットフォーム技術の採用を検討 
 ◦ リプレイス/エンハンスの開発工数半減が期待できる 
 
 • 技術検証→Flutterの開発生産性が最も高いと実感

    
 ◦ hot reload / hot restart
 ◦ 宣言的なUI構築
 ◦ 既成部品の充実
 
 • じゃらんnetアプリのリプレイスにFlutterを採用 
 
 ※ なおクロスプラットフォーム技術の比較検討の詳細については 
   発表の主旨とずれてしまうため割愛 
 10

  6. 1. じゃらんnetのご紹介
 
 2. じゃらんnetアプリをFlutterリプレイスしている背景
 
 3. じゃらんnet Flutterリプレイスの道のり
 a.

    Add-to-appを使用したFlutterの部分的導入
 b. じゃらん全体のFlutter化を見据えた構成変更
 c. ネイティブコードの段階的なFlutterへの置き換え
 
 4. これまでの道のりの振り返り
 説明の流れ
 11

  7. • Flutterでフルリプレイスする場合 
 ◦ ネイティブの開発チームの案件開発を停止する必要がある
 ◦ フルリプレイスするための大規模なFlutter開発体制を構築する必要がある
 
 
 


    
 
 • Flutter自体の有効性が不明瞭な状況で実施するのはリスクが大きかった 
 
 一度にまとめてFlutterフルリプレイスするのは困難だった
 13
 iOS 開発チーム Android 開発チーム Flutter 開発チーム じゃらんnetアプリ 開発チーム 案件を停止する必要がある 
 大規模な開発体制を 
 構築する必要がある 

  8. • ビジネスサイドからの目線としても実績がない状況で 
 新しい技術を使用したフルリプレイスは懐疑的だった 
 
 
 • 一度にフルリプレイスするのはリスク大/難易度高と判断 


    
 • そこでフルリプレイスするのではなく、 
 段階的に徐々にFlutterへ置き換えていく方針を採ることにした 
 一度にまとめてFlutterフルリプレイスするのは困難だった
 14
 Flutterなるものは 本当に大丈夫なのか?
  9. STEP2
 Flutterリプレイスの3つのSTEP
 Flutter Add-to-app 16
 STEP3
 ネイティブ
 ネイティブ
 Flutter
 Flutter

    ネイティブ
 Flutter
 Flutter Flutter Flutter • じゃらんnetアプリのFlutterリプレイスは3つのSTEPで構成される 
 STEP1

  10. Flutterリプレイスの3つのSTEP
 Flutter Add-to-app 17
 STEP2
 STEP3
 ネイティブ
 ネイティブ
 Flutter
 Flutter

    ネイティブ
 Flutter
 Flutter Flutter Flutter • Add-to-appを使用してFlutterを一部導入 
 ◦ 狙い1: Flutter自体の有効性検証 
 ◦ 狙い2: Flutterが開発生産性へ寄与することを示す実績を作ること 
 STEP1

  11. Flutterリプレイスの3つのSTEP
 Flutter Add-to-app 18
 STEP2
 STEP3
 ネイティブ
 ネイティブ
 Flutter
 Flutter

    ネイティブ
 Flutter
 Flutter Flutter Flutter • 既存ネイティブプロジェクトを1つのFlutterプロジェクトに変更する 
 ◦ 狙い: じゃらんnetアプリ全体をFlutterリプレイスするための下地作り 
    段階的にFlutterリプレイスしやすい環境を作ること 
 STEP1

  12. Flutterリプレイスの3つのSTEP
 Flutter Add-to-app 19
 STEP2
 STEP3
 ネイティブ
 ネイティブ
 Flutter
 Flutter

    ネイティブ
 Flutter
 Flutter Flutter Flutter • 画面単位でネイティブのソースを徐々にFlutterに置き換えていく 
 STEP1

  13. Flutterリプレイスの3つのSTEP
 Flutter Add-to-app 20
 STEP2
 STEP3
 ネイティブ
 ネイティブ
 Flutter
 Flutter

    ネイティブ
 Flutter
 Flutter Flutter Flutter • これらの段階を経て最終的にはじゃらんnetアプリのフルFlutter化を目指す 
 STEP1

  14. Add-to-app (Add Flutter to existing app)
 
 • 独立したiOS/AndroidプロジェクトにFlutterの画面やDartのロジックを 


    モジュールとして組み込むことができる機能 
 
 • module typeのFlutterプロジェクトを構築しネイティブプロジェクトに組み込む 
 
 
 
 
 
 22
 じゃらん
 iOS
 アプリ
 Flutter
 プロジェクト
 (module type)
 じゃらん
 Androidアプ リ
 
 
 
 
 

  15. • この段階ではまだじゃらんnetアプリに 
 Flutterを全面的に採用する決断には至っていない 
 ◦ →小さいコストでFlutterを導入し、Flutter自体の有効性検証を行いたい 
 
 •

    Add-to-appはドキュメントが充実していて、 
 Flutterを導入する際のコストが最も小さいと判断 
 
 • まずはAdd-to-appで一部Flutterを導入した 
 
 ※ なおAdd-to-appはドキュメントが充実しているため 
   その導入手順の説明は本発表では割愛 
 
 Add-to-appを使用した背景
 26

  16. • 総じて期待していたメリットを得られたと実感 
 じゃらん遊び・体験のFlutter化において 
 • iOS/Androidの仕様差分をなるべく減らす 
 • iOS/Android両方をマテリアルデザインで統一

    
 
 • 開発以外の工数も削減
 Add-to-appでFlutterを導入してみて
 27
 ほとんどのコードを
 Dartで統一でき
 開発工数はほぼ半分に
 開発工数
 要件検討工数
 デザイン作成工数
 5割減
 5割減
 3割減

  17. • hot reload/hot restartによる高速な開発イテレーション 
 
 • 既成部品の充実
 
 •

    IDEの機能充実
 
 
 
 • 従来のネイティブ開発と比較して2、3割程度開発効率向上を実感(主観値)
 Add-to-appでFlutterを導入してみて
 28

  18. • Add-to-appでFlutterを一部導入した際にハマったポイント 
 • 得られたメリットの詳細
 
 • 参考
 • YouTube動画:

    https://www.youtube.com/watch?v=Wi0Wmv3B8Uk 
 • SlideShare: https://www.slideshare.net/RecruitLifestyle/flutter-238676480 
 
 iOSDC2020: 「Flutter以降の苦労と乗り越えた先に得られたもの」
 30

  19. • Flutter自体の有効性の検証ができた 
 
 • またビジネスサイドからの懐疑的な目線に対してもファクトとして 
 Flutterの開発生産性寄与を示すことができた 
 


    • じゃらんnetアプリ全体にFlutterを展開していく 
 ◦ 前準備としてプロジェクトの構成変更を実施 
 Add-to-appを使用したFlutterの一部導入によって
 32
 Flutterいいね!
  20. • iOSプロジェクトとAndroidプロジェクトが独立して存在 
 • FlutterプロジェクトがAdd-to-appでそれぞれ組み込まれている 
 Add-to-app時点のじゃらんnetアプリのプロジェクト構成
 33
 じゃらんnetアプリ iOSプロジェクト

    じゃらんnetアプリ Androidプロジェクト じゃらん遊び・体験 Flutterプロジェクト (module) Add-to-app
 Add-to-app
 この状況だとFlutter
 コードを追加する際に
 都度moduleとして
 用意する必要がある

  21. • iOS/Androidプロジェクトを1つのFlutterプロジェクトにすることができれば 
 ◦ moduleとしてFlutterコードを用意する必要がなくなる 
 ◦ 任意のタイミングでFlutter画面を表示したり 
 Dartコードを呼び出したりしやすくなる

    
 
 
 
 
 
 
 iOS/Androidプロジェクトを一つのFlutterプロジェクトへ
 34
 じゃらんnetアプリ iOSプロジェクト じゃらんnetアプリ Androidプロジェクト じゃらん遊び・体験 Flutterプロジェクト (module) Add-to-app
 Add-to-app
 じゃらんnetアプリ Flutterプロジェクト(app) じゃらんnetアプリ iOSプロジェクト じゃらんnetアプリ Androidプロジェクト じゃらんnet iOS/Androidプロジェクトを1つのFlutterプロジェクトへ 

  22. • しかしAdd-to-appとは違い
 「既存のネイティブプロジェクトを1つのFlutterプロジェクトに変更する方法」 
 はドキュメントにもなければ、探した範囲ではネット上にも存在しなかった 
 
 • そこで自分たちでFlutterプロジェクトの構造やビルドの流れを確認することで 


    実現方法を調査した
 
 ※ 実現方法についての説明はあまりにも詳細な実装や修正の話になってしまうため、 
   Appendixに記載。本発表では詳細なところまでは説明せず、どの様なことが 
   必要になるのか大まかな考え方について説明。 
 iOS/Androidプロジェクトを一つのFlutterプロジェクトへ
 35

  23. • 既存のネイティブプロジェクトをFlutterとして実行するためには 
 ネイティブのソースファイルをFlutterプロジェクト内に配置する必要がある 
 
 • Flutterプロジェクトはルートディレクトリにios/とandroid/があり 
 ここにiOSのソースファイルとAndroidのソースファイルを配置する

    
 ① Flutterプロジェクト内にネイティブのソースファイルを配置
 37
 じゃらんnet Androidプロジェクトのファイル群を配置 
 じゃらんnet iOSプロジェクトのファイル群を配置 
 ※ ファイル配置の手順についてはAppendixに記載
  24. • Flutterはいくつかのファイルや設定の命名を 
 特定の名前であることを前提にしている(主にiOS側) 
 
 • ios/配下のiOSプロジェクト名: 「Runner」 


    • BuildConfiguration名: 「{FlutterのBuildMode}-{Flavor名}」 
 
 ※ 命名の詳細についてはAppendixに記載 
 
 ② ファイルや設定の命名をFlutterが前提とする命名にする
 38

  25. • app typeのFlutterプロジェクトの以下の部分を確認し必要な処理を呼び出す 
 ◦ iOS: Podfile、プロジェクトファイルのBuild Phase 
 


    
 
 
 
 ◦ Android: build.gradle、settings.gradle 
 
 
 
 ※ こちらの手順についてもAppendixの方に記載 
 ③ Flutterが保持するビルド用の処理を正しい順番で呼び出す
 39
 例)
 例)

  26. • Flutterプロジェクトで包んだネイティブのコード を画面単位で除去していき、
 Dartで実装し直すことでFlutterに 
 置き換えていく
 
 • Add-to-appの状態から構成変更を 


    行なったことで任意の箇所をFlutterに 
 置き換えやすくなった
 
 • 最終的にはじゃらんnetアプリ全体のFlutter化 を目指していく
 プロジェクト構成変更後の段階的なリプレイス
 41
 ネイティブ
 Flutter Flutter Flutter Flutter

  27. 1. じゃらんnetのご紹介
 
 2. じゃらんnetアプリをFlutterリプレイスしている背景
 
 3. じゃらんnet Flutterリプレイスの道のり
 a.

    Add-to-appを使用したFlutterの部分的導入
 b. じゃらん全体のFlutter化を見据えた構成変更
 c. ネイティブコードの段階的なFlutterへの置き換え
 
 4. これまでの道のりの振り返り
 説明の流れ
 42

  28. • 当初の懸念
 ◦ Flutter自体の有効性
 ◦ ビジネスサイドからの懐疑的な目線 
 
 • 段階的にリプレイスを実施したことで少しずつ試しながら推進

    
 ◦ リスクを抑えながらリプレイスを推進することができている 
 
 • リプレイスの過程でFlutterの生産性寄与を実績として作ることができた 
 ◦ 開発外への決裁でも信頼性のある提案をしつつ 
 更なるFlutter展開の合意を得ることができている 
 
 段階的なFlutterリプレイスの実施による懸念解消
 43
 Flutterいいね!
  29. • 当初の懸念
 ◦ Flutter自体の有効性が不明瞭な状態で 
 以下を実施するのはリスクが大きい 
 ▪ ネイティブの開発チームの案件を停止
 ▪

    大規模なFlutterの開発体制の構築
 
 
 • Flutterチームが特定の画面をリプレイスしている間 
 ネイティブチームで他画面の案件開発を並行 
 ◦ →案件開発の停止が不要
 
 • 最初は小規模な開発体制でリプレイスを開始し 
 必要に応じて体制を拡大する
 
 段階的なFlutterリプレイスの実施による懸念解消
 44
 iOS 開発チーム Android 開発チーム Flutter 開発チーム じゃらんnetアプリ 開発チーム 案件の停止
 大規模な
 開発体制の構築
 画面 A 画面 B Flutter開発Tで
 リプレイス
 iOS/Android開発T
 で案件の開発
 並行

  30. 画面A あまり 改修 されない 画面B 頻繁に 改修 される 画面C あまり

    改修 されない • アプリ内の頻繁に改修する画面を優先的にFlutter化することで、 
 小さい工数で早期にFlutterのメリットを享受できる 
 段階的リプレイスの副次的メリット: 効果が大きいところから優先的
 にFlutter化できる
 45
 後回し
 後回し
 先にFlutter化
 早期にFlutterのメリットを享受できる

  31. 段階的リプレイスの副次的メリット: 既存のネイティブロジックを
 適宜使用できる
 • MethodChannel
 ◦ Dartとネイティブコードを
 連携できる機能
 
 •

    MethodChannelを使用することで 
 Dartで実装し直さなくても、構築済みの 
 ネイティブの処理を呼び出すことができる 
 
 • じゃらん遊び・体験をAdd-to-appで 
 Flutter化した際、認証のロジックを 
 Dartで作り直す工数が大きかったため、 
 構築済みのネイティブ認証ロジックを使用 
 
 46

  32. • 既存iOS/Androidプロジェクトは
 Flutterで連携されることを前提としていない 
 
 • リプレイスする際にネイティブとの連携箇所でiOS/Androidの形式が異なって 
 いて、その違いを吸収するために設計が難化するケースがある 


    
 • 例) 画面遷移引数
 画面遷移引数の形式が 
 iOS/Androidで異なる 
 • どの様な構造で渡す? 
 • Flutter内では
 どう管理する?
 段階的なFlutterリプレイスの悩みポイント: 設計の難化
 47
 Flutter 画面A iOS 画面B And roid 画面B {
 key1: String
 key2: int
 }
 {
 key1:int
 key3: Map
 }

  33. • 我々がAdd-to-appによる部分的導入を実施した背景 
 ◦ 小さいコストでFlutter自体の有効性検証と
 実績作りをしたかったため
 
 • このフェーズの必要性はチーム状況によって変わるが 


    飛ばせるなら飛ばした方が良いと今は考えている 
 ◦ 現在はFlutter自体の品質は一定信頼できるはず 
 ◦ Add-to-app固有のバグにはまったり、運用を検討 
 したりするコストは多少なりともかかる 
 
 • 小さく始めて実績を積みたい場合は採用するのも一つの選択肢 
 
 
 Add-to-appを使用したFlutterの有効性検証について
 50
 Flutter Add-to-app ネイティブ
 STEP1

  34. • 話したこと
 ◦ じゃらんnetアプリFlutterリプレイスの道のり
 i. Add-to-appを使用したFlutterの部分的導入 
 ii. じゃらん全体のFlutter化を見据えた構成変更 


    iii. ネイティブコードの段階的なFlutterへの置き換え 
 
 ◦ 段階的リプレイスのメリット/デメリットと、 
 段階的にリプレイスする場合今ならどの様な方針を採るかについて 
 
 • リプレイスする場合どの様な方針を採るかは 
 プロダクト/チーム状況に合わせて検討する必要がある 
 まとめ
 53

  35. Run Scriptの追加
 
 • ↓の2つのRun ScriptをBuild Phaseに追加する 
 ◦ 「Run

    Script - xcode_backend.sh build」はCompile Sourcesの前
 ◦ 「Run Script - xcode_backend.sh embed_and_thin」はCompile Sourcesの後
 68

  36. • iOS: FlutterViewController
 Android: FlutterActivity
 に遷移することでFlutterの画面を表示 
 Flutterの画面を表示するために重要なクラス
 74
 FlutterEngine

    FlutterViewController FlutterActivity FlutterView Flutter
 View
 Controller
 
 Flutter
 Activity
 View
 Controller
 
 Activity
 
 画面遷移