各画面遷移方法のメリットデメリット

各画面遷移方法のメリットデメリット

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

くらいの差で、普通のアプリなら「どれを選んだから重い」というより、「その中に何を描画しているか」の方が圧倒的に効きます。

タイトルとURLをコピーしました