技術カンファレンス FlutterKaigi 2024 参加記録
概要
FlutterKaigi 2024は、Flutterの最新情報や実践的な技術を学ぶためのカンファレンスです。本記事では、1日目と2日目の参加記録を共有します。
今年で4回目の開催で、2日間で総来場者数は約350名とのこと。
セッション ホール
セッション(講演)はホールAとBの2つで分かれており、片ホールだけでも約100名ほど確認できた。
スポンサーブース
ホールとは別にスポンサーブースが約10か所ほど設けられており、スタンラリー形式ですべてを回るとグッズの抽選を行うことができる。
ポストイットでお題に対し、各参加者の抱えている問題やおすすめする形式などが張り出されており興味深い。
状態管理パッケージはProvider、Riverpod、BLoC、その他という宗派争いが起きており、Riverpodが現状一強となっていた。
1日目
1. ネットスーパーがスクリーンリーダーに対応した話 ~あるいはアクセシビリティ向上によるユーザー獲得~
- ウェブアクセシビリティの合理的配慮の提供が義務化
- 2024年4月から、障がい者から要望があり合理的な理由であれば対応が必要となった
- モバイルはスクリーンリーダー標準搭載
- スクリーンリーダ利用者の9割がiOS
- そもそもiOS国内シェアが高いことも影響していそう
- スクリーンリーダ利用者の9割がiOS
- Windowsは別途、読み上げソフトが必要
- PC-Talker
- 有料
- 利用者数が多い
- NVDA
- 無料
- オープンソース
- PC-Talker
- スクリーンリーダー用に可読部の設定が重要
- Web対応は現状バグが多く難しい
2. Flutterアプリで可用性を向上させたFeatureFlagの運用戦略とその方法
- トランクベース開発
- 機能の半分実装(細かい単位)だとしてもmasterへマージする
- コンフリクトを軽減できる
- 1回のプルリクエストの変更行を300行以内に収めるため
- Feature flag
- 未完成の機能を隠すためのフラグ。トランクベース開発のような場合は必須
- 常に20個弱のフラグを運用
- A/Bテストにも活用
- 主に2種類
- ローカルでの埋め込みタイプ
- リモートから切り替えられるタイプ(Ops Toggle)
- 流れ
- 最初の開発段階は1で、リリース時は2へ移行
- リリース後に新機能で問題があれば2を操作し隠すことで、別途ビルド&リリースの手間が不要となる(特にアプリであれば審査に時間を取られずに済む)
- リリースから1か月後、問題が発生しなければフラグは削除する
- フラグによる隠し漏れチェック
- E2Eテスト
- CIによるコードレビューツール(Danger)※Lintの方が理想、CIより段階が早いので
- 基本は根本部分でフラグ分けだが冗長になる可能性あり(簡単な色・サイズ変更であればこの限りでない)
3. ステートマシンで実現する高品質なFlutterアプリ開発
- ステートマシンとは有限個の状態と遷移を定義するもの
- 自販機などの設計に該当
- RiverPodのAsyncValueもステートマシンの考え方
- 状態毎にクラス化することで、その状態で持ちうるデータ変数や振る舞いを限定化
- 中身はstreamで状態を受け渡し
4. Flutterによる効率的なAndroid・iOS・Webアプリケーション開発の事例 - スタディサプリ for SCHOOL
- アプリ&Webを1000ファイル10万行のdartコードへリプレイスできた
- Flutter Webはデメリットが多い
- Safariとの相性が悪い
- HTML Rendererが非対応になる予定(CanvasKitなどへの移行)
5. アニメーションを最深まで理解してパフォーマンスを向上させる
- Flutter3.24以上でアニメーションパフォーマンス向上(skia ⇒ impellerに変わった)
- Implicit Animation
- 値が変わったときにアニメーション
- Animation Controllerが不要(簡易的に実装できる)
- Explicit Animation
- 複雑な実装に有効
- Dev Tools
- パフォーマンス計測は事前コンパイルされているProfile Modeで行うべき(Debugの場合アプリを読み込む段階でコンパイルされるため)
- Frame Chart
- 1フレーム=1バー
- CPU thread については難解
- Rster Thred
- GPUについて
- jank
- フレーム数的に16msを超えると重い
- RepaintBoundary
- 通常は変更ウィジェットの親ウィジェットまでさかのぼって更新されるが、これを付与すると親と切り離すことができ、描画負荷を減らせる。(devtoolsのmetrics値が減る)
- GPUへのコストを増やすため注意
6. Shorebirdを活用したFlutterアプリの即時アップデート:Code Pushの実践と可能性
- Shorebird
- コードプッシュ(軽微な変更パッチ当て)するための有料サービス
- 本来は公式対応予定だったが、コストに見合わないと判断され凍結。Flutterからフォークされ別運営
- アプリ審査を待たずにパッチを割り当てることが可能
- アプリ審査は別途自己申告で必要
- アプリのジャンルを変えるなど大幅な変更は規約違反
- 1利用者=1パッチ 必要なため課金額に注意
- 新規にインストールするユーザ場合、古いバージョンのままなため公式通りのリリース手順がいる
7. Master of Isolate
- Isolate
- 同期処理を別スレッドに移してブロッキングを防ぐ
- UIのカクつきを無くすためのもの(16ms以下にする)
- 生成に101.78ms必要なため、この切り替えコストを考慮すべき
- 通常は非同期処理のasyncでブロッキングを防いでいる
- 非同期処理でも内部的には同期処理が多い可能性もある
8. Flutterテスト戦略の再考 〜品質と効率のバランスを求めて〜
- テスト
- 小さく始めて文化を育てていくのがよい
- 属人化しないように
9. 僕のstate restorationアカデミア
- restoration
- 一時的データ保存(進捗状況など)
- Androidは1Mbまで
2日目
1. Flutterアプリにおけるユーザー体験の可視化と計測基盤構築
- SLI
- 定量的な値
- 例:クラッシュフリーユーザ率
- SLO
- SLIの目標値
- 例:24時間内の99%維持
- CUJ
- 目標達成に至るまでに必要な1単位のタスク
- 細かく分割して考えることで、どこでユーザがつまづいたかを調べる
- 全て調べるのは大変なのでコア機能に絞る
- 一般的にはCUJ単位ではなく、APIリクエスト数で計測されている
- プラットフォームに依存せず済むため
- 計測がバックエンド側の発祥文化のため
- クライアント起因によるAPIで呼ばれない操作もCUJにより拾えるようにするのが理想
- パスワード入力
- 入力エラー
- キャンセルなど
- Sentryでエラーログを通知
- クラッシュ検知手法
- CUJの前段階でlocaldatabaseにフラグを格納(preferenceはキー衝突の可能性があるのでNG)
- 一連処理が終わったらフラグを消す
- 次回起動時、フラグが消えていない場合はクラッシュなので通知処理を行う
2. 出前館アプリにおけるFlutterアプリ設計とそれを支えるCICD環境の進化
フォルダ分け方法
- ドメイン(ページ)でフォルダ分け
- 機能でフォルダ分け(登壇者はこれを使ってる)
- パッケージ化してそこ経由で参照(冗長になるが衝突は発生しずらい)
- 1~3に進むへ連れて、小規模~大規模向けへとなっていく
- 1は大規模な場合、重複ファイルが増え冗長となる
- 3は命名の衝突を回避できるが小規模な場合、冗長となる
- アセット呼び出し
1.直接パス入力(タイポが発生する)
2.flutter_gen(事前にbuild_runnerが必要だがタイポがなくなる) - CI/CD
- オンプレで実装
- TeamCityというサービスを使用
- OSのバージョンによっては、ビルドできるバージョンも制限される場合があるため、ロールバックに備えて複数台が必要になる可能性もあり(今年度初頭のiOS対応にて発生)
3. Monetizing Your Indie Flutter App to $1k in Monthly Revenue and Beyond
- 以下の3点を考える
- ターゲット
- 解決する問題
- 競合
- 収益方法
- 広告
- ユーザ数が少ない初期段階であれば意味がない
- アプリ内通貨
- 買い切り
- アプリの性質として、利用頻度が少ないものであればこちらの方が多く回収できる
- サブスク(推奨)
- 広告
- 広報
- 広告
- アプリのジャンルや国によって特性があるためPDCAサイクルを回す
- キーワード
- 説明文
- GoogleであればYoutubeや検索エンジンなど幅広く掲載される
- アプリのジャンルや国によって特性があるためPDCAサイクルを回す
- 出版社へのプレスリリース
- 向こうの仕事の手間を減らすつもりで丁寧に作る
- 関係性の構築
- SNS運営
- 手軽
- 広告
- サブスクの価格表
- 表示回数と売り上げが比例する
- デザインによって売り上げに影響がでるのでPDCAサイクルを回す
- 多少冗長になっても丁寧な説明をすべき
- 納得感が得られ、キャンセル率の低下が見込める
- 即購入のパターンが減る
- 顧客の維持率が売り上げに大きく響く
- 魅力的な製品へ
- ユーザへの報酬
- ログインボーナスなど
4. Firebase Dynamic Links終了に備える:FlutterアプリでのAdjust導入とディープリンク最適化
- FDL
- 廃止予定(クッキー制限の影響か)
- アプリストア遷移・アプリ起動を動的に選択する挙動のURL
- 広告に応じたアクセス数の計測など
- アプリリンク/ユニバーサルリンク
- インストール済みの場合に自動でアプリを起動するURL
- FDLからこちらへの移行が必要
- 「インストール済みの場合」と 権限が制限された
- ディープリンク
- 外部の有料サービス(リンクプロバイダ)でないと提供できない? 例:adjust
- 新規ダウンロード特典・アフィリエイト特典などを提供できる
5. マッチングアプリ『Omiai 』のFlutterへのリプレイスの挑戦
- ビジネスロジックではcontexを使うのは避けるべき
- テストが困難になる
- ウィジェットUI内での例外処理せず、ビジネスロジック内ですべき
- フォルダ分け
- FlutterコードとDartコードで分ける
- 前者はUI構成のためにウィジェットの知見が必要
- 後者は状態管理パッケージとHTTPリクエスト周りさえ覚えればOk
- FlutterコードとDartコードで分ける
- 画面遷移はauto_route
- public_member_api_docs
- public関数へのドキュメンテーションを強制するためのパッケージ
- スニペットとCopilotを組み合わせることでテストの生成工数を大幅省略
6. Effective Form ~ Flutterによる複雑なフォーム開発の実践 ~
- バリデーション
- 入力形式があっているかチェック
- チェックのタイミングが早すぎると、デフォルトでエラー判定になり不自然
- dirty
- バリデーションするタイミング用のクラス
- 基本フォーム送信時
- 状態は画面遷移したとしても1か所から参照すべき
- 状態毎にクラス化
- 持つべき値を限定できる
全体の感想
肌感として、アプリについては特に問題がなさそうだが、Flutter Web対応については各社色々と四苦八苦している印象だった。だが、それをもってしても、人材不足な昨今1つのフレームワークでマルチプラットフォーム対応できるメリットの方が勝っていると思われる。
Flutterに限らず、トランクベース開発・Feature flagやフォルダ分け方法、API取得状態のクラス化などは他の言語でも使えそうな考え方だと感じた。