安定性の問題を診断する

不要な再コンポーズや過剰な再コンポーズが原因でパフォーマンスの問題が発生している場合は、アプリの安定性をデバッグする必要があります。このガイドでは、そのためのいくつかの方法について説明します。

Layout Inspector

Android Studio の Layout Inspector を使用すると、アプリ内でどのコンポーザブルが再コンポーズされているかを確認できます。Compose がコンポーネントを再コンポーズまたはスキップした回数が表示されます。

Layout Inspector の再コンポーズとスキップの回数

Compose コンパイラ レポート

Compose コンパイラは、安定性推論の結果を検査用に生成できます。この出力を使用すると、スキップ可能なコンポーザブルとスキップ不可能なコンポーザブルを特定できます。次のサブセクションでは、これらのレポートの使用方法の概要を説明します。詳細については、技術ドキュメントをご覧ください。

設定

Compose コンパイラ レポートはデフォルトでは有効になっていません。コンパイラ フラグを使用して有効にできます。正確な設定はプロジェクトによって異なりますが、Compose コンパイラ Gradle プラグインを使用するプロジェクトでは、各モジュールの build.gradle ファイルに次を追加できます。

  android { ... }

  composeCompiler {
    reportsDestination = layout.buildDirectory.dir("compose_compiler")
    metricsDestination = layout.buildDirectory.dir("compose_compiler")
  }

プロジェクトのビルド時に Compose コンパイラ レポートが生成されるようになりました。

出力例

reportsDestination は 3 つのファイルを出力します。JetSnack の出力例を次に示します。

  • <modulename>-classes.txt: このモジュールのクラスの安定性に関するレポート。サンプル
  • <modulename>-composables.txt: モジュール内のコンポーザブルが再起動可能でスキップ可能であるかについてのレポート。サンプル
  • <modulename>-composables.csv: スプレッドシートにインポートしたり、スクリプトを使用して処理したりできる、コンポーザブル レポートの CSV バージョン。サンプル

コンポーザブル レポート

composables.txt ファイルには、指定されたモジュールの各コンポーザブル関数について、パラメータの安定性、再起動可能かどうか、スキップ可能かどうかなどの詳細が記載されています。以下は JetSnack の架空の例です。

restartable skippable scheme("[androidx.compose.ui.UiComposable]") fun SnackCollection(
  stable snackCollection: SnackCollection
  stable onSnackClick: Function1<Long, Unit>
  stable modifier: Modifier? = @static Companion
  stable index: Int = @static 0
  stable highlight: Boolean = @static true
)

この SnackCollection コンポーザブルは、完全に再起動可能、スキップ可能、安定しています。これは一般的に推奨されますが、必須ではありません。

一方、別の例を見てみましょう。

restartable scheme("[androidx.compose.ui.UiComposable]") fun HighlightedSnacks(
  stable index: Int
  unstable snacks: List<Snack>
  stable onSnackClick: Function1<Long, Unit>
  stable modifier: Modifier? = @static Companion
)

HighlightedSnacks コンポーザブルはスキップできません。Compose は、再コンポーズ中にスキップすることはありません。これは、パラメータが変更されていない場合でも発生します。これは、unstable パラメータ snacks が原因です。

クラスレポート

ファイル classes.txt には、指定されたモジュールのクラスに関する同様のレポートが含まれています。次のスニペットは、クラス Snack の出力です。

unstable class Snack {
  stable val id: Long
  stable val name: String
  stable val imageUrl: String
  stable val price: Long
  stable val tagline: String
  unstable val tags: Set<String>
  <runtime stability> = Unstable
}

参考までに、Snack の定義は次のとおりです。

data class Snack(
    val id: Long,
    val name: String,
    val imageUrl: String,
    val price: Long,
    val tagline: String = "",
    val tags: Set<String> = emptySet()
)

Compose コンパイラは Snack を不安定としてマークしました。これは、tags パラメータの型が Set<String> であるためです。これは MutableSet ではないため、不変型です。ただし、SetListMap などの標準コレクション クラスは、最終的にはインターフェースです。そのため、基盤となる実装は変更可能である可能性があります。

たとえば、val set: Set<String> = mutableSetOf("foo") と記述できます。変数は定数で、宣言された型は可変ではありませんが、実装は可変です。Compose コンパイラは宣言された型しか認識できないため、このクラスの不変性を確認できません。そのため、tags は不安定とマークされます。