Diagnostica i problemi di stabilità

Se riscontri problemi di prestazioni dovuti a una ricomposizione non necessaria o eccessiva, ti consigliamo di eseguire il debug della stabilità dell'app. Questa guida illustra diversi metodi per eseguire questa operazione.

Controllo layout

Il Controllo layout in Android Studio ti permette di vedere quali componenti componibili vengono ricomposti nella tua app e mostra il numero di volte in cui Compose ha ricomposto un componente o l'ha ignorato.

Ricomposizione e numero di salti nella finestra Controllo layout

Crea report di compilazione

Il compilatore Compose può restituire i risultati dell'inferenza della stabilità a scopo di ispezione. Questo output ti consente di determinare quali elementi componibili sono ignorabili e quali no. Le seguenti sottosezioni riepilogano come utilizzare questi report, ma per informazioni più dettagliate consulta la documentazione tecnica.

Configura

I report del compilatore del compilatore non sono abilitati per impostazione predefinita. Puoi attivarli con un flag di compilazione. La configurazione esatta varia a seconda del progetto, ma per la maggior parte dei progetti puoi incollare il seguente script nel file build.gradle principale.

trendy

subprojects {
  tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).configureEach {
        kotlinOptions {
            if (project.findProperty("composeCompilerReports") == "true") {
                freeCompilerArgs += [
                        "-P",
                        "plugin:androidx.compose.compiler.plugins.kotlin:reportsDestination=" +
                                project.buildDir.absolutePath + "/compose_compiler"
                ]
            }
            if (project.findProperty("composeCompilerMetrics") == "true") {
                freeCompilerArgs += [
                        "-P",
                        "plugin:androidx.compose.compiler.plugins.kotlin:metricsDestination=" +
                                project.buildDir.absolutePath + "/compose_compiler"
                ]
            }
        }
    }
}

Kotlin

subprojects {
    tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile>().configureEach {
        kotlinOptions {
            if (project.findProperty("composeCompilerReports") == "true") {
                freeCompilerArgs += listOf(
                    "-P",
                    "plugin:androidx.compose.compiler.plugins.kotlin:reportsDestination=${project.buildDir.absolutePath}/compose_compiler"
                )
            }
            if (project.findProperty("composeCompilerMetrics") == "true") {
                freeCompilerArgs += listOf(
                    "-P",
                    "plugin:androidx.compose.compiler.plugins.kotlin:metricsDestination=${project.buildDir.absolutePath}/compose_compiler"
                )
            }
        }
    }
}

Esegui l'attività

Per eseguire il debug della stabilità dei componibili, esegui l'attività come indicato di seguito:

./gradlew assembleRelease -PcomposeCompilerReports=true

Output di esempio

Questa attività genera tre file. Di seguito sono riportati output di esempio di JetSnack.

  • <modulename>-classes.txt: un report sulla stabilità dei corsi in questo modulo. Esempio.
  • <modulename>-composables.txt: un report sul livello di riavvio e ignorabile dei componibili all'interno del modulo. Esempio.
  • <modulename>-composables.csv: una versione CSV del report sui componibili che puoi importare in un foglio di lavoro o elaborare utilizzando uno script. Esempio

Report sui materiali componibili

Il file composables.txt descrive in dettaglio ogni funzione componibile per il modulo in questione, inclusa la stabilità dei relativi parametri e se sono riavviabili o ignorabili. Di seguito è riportato un esempio ipotetico tratto da 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
)

Questo componibile SnackCollection è completamente riavviabile, ignorabile e stabile. In genere questa opzione è preferibile, anche se non obbligatoria.

Diamo un’occhiata a un altro esempio.

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
)

Il componibile HighlightedSnacks non è ignorabile. Compose non la salta mai durante la ricomposizione. anche se nessuno dei parametri è stato modificato. Il motivo è il parametro unstable, snacks.

Report sui corsi

Il file classes.txt contiene un report simile sulle classi nel modulo in questione. Il seguente snippet è l'output per la classe 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
}

Come riferimento, di seguito è riportata la definizione di Snack:

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

Il compilatore di Compose ha contrassegnato Snack come instabile. Questo perché il tipo del parametro tags è Set<String>. Questo è un tipo immutabile, dato che non è un MutableSet. Tuttavia, le classi di raccolta standard come Set, List e Map sono in definitiva interfacce. Di conseguenza, l'implementazione di base potrebbe essere ancora modificabile.

Ad esempio, potresti scrivere val set: Set<String> = mutableSetOf("foo"). La variabile è costante e il tipo dichiarato non è mutabile, ma la sua implementazione è ancora modificabile. Il compilatore Compose non può essere sicuro dell'immutabilità di questa classe poiché vede solo il tipo dichiarato. Di conseguenza, contrassegna tags come instabile.