各画面遷移方法のメリットデメリット
Composeでは「どれを使うか」でUXだけでなく、描画コストや状態管理の複雑さも変わります。
結論(表示速度・軽さ優先)
一般的には
| 軽さ | 方法 |
|---|---|
| ★★★★★ | Navigation |
| ★★★★☆ | ModalBottomSheet |
| ★★★☆☆ | Dialog |
| ★★☆☆☆ | FullScreen Dialog |
です。
ただし「軽い=速い」ではなく、用途との相性もあります。
1. Navigation Compose
navController.navigate("detail")
メリット
- Android標準の画面遷移
- ViewModelとの相性が良い
- ライフサイクル管理が楽
- 戻るボタン対応が自然
- 大規模アプリ向き
デメリット
- モーダル感は薄い
- 「一時的な入力画面」には大げさ
処理負荷
かなり軽いです。
実際には
現在画面
↓
新しいComposableを描画
しているだけです。
アニメーションもシンプルなので負荷は低め。
2. ModalBottomSheet
ModalBottomSheet {
Content()
}
メリット
- Material Design準拠
- 下から出るUIが自然
- 小規模な設定画面向き
例
- フィルター
- ソート
- メニュー
- 編集
デメリット
- 背景画面も残る
- ジェスチャー制御が少し複雑
- 重いComposableを入れるとカクつく
処理負荷
中程度です。
理由は
親画面
+
BottomSheet
を同時に保持するため。
つまり
一覧画面
↓
BottomSheet表示
一覧画面は生きている
BottomSheetも描画
となります。
巨大なLazyColumnを2つ表示すると結構重くなります。
3. Dialog
Dialog { ... }
メリット
- モーダル感が強い
- 実装が簡単
- 確認画面向き
例
- 削除確認
- パスワード入力
- エラー表示
デメリット
- Androidらしさは少し薄い
- 複雑な画面を入れると管理しにくい
処理負荷
BottomSheetと同程度〜やや重め。
なぜなら
Activity
└ Dialog Window
のように別ウィンドウ的に扱われるためです。
ただし普通の確認ダイアログ程度なら誤差です。
4. FullScreen Dialog
Dialog(
properties = DialogProperties(
usePlatformDefaultWidth = false
)
)
メリット
- SwiftUIのfullScreenCover感がある
- 背景を隠せる
デメリット
- Navigationの代用品になりがち
- 戻る管理が面倒
- ViewModel共有がやや複雑
処理負荷
今回の4つでは最も重いです。
理由は
元画面
+
フルスクリーンダイアログ
を保持するため。
見えなくても裏側のComposableは残っています。
実務での選択基準
私ならこんな感じです。
Navigation
- 詳細画面
- 編集画面
- 設定画面
→ 第一候補
BottomSheet
- ソート
- フィルター
- 選択メニュー
→ 第一候補
Dialog
- 確認
- 入力
- 警告
→ 第一候補
FullScreenDialog
- 本当にモーダルである必要がある場合のみ
→ あまり使わない
Compose特有の注意点
重さの原因は実は「表示方法」よりも中身です。
例えば
ModalBottomSheet {
LazyColumn {
items(5000) {
HeavyComposable()
}
}
}
は重いですし、
navController.navigate("detail")
で遷移した先に同じ内容があればやはり重いです。
なので実際には、
画面遷移方式の差 < Composableの重さ
になることがほとんどです。
体感では、
Navigation ≒ ModalBottomSheet > Dialog > FullScreenDialog
くらいの差で、普通のアプリなら「どれを選んだから重い」というより、「その中に何を描画しているか」の方が圧倒的に効きます。