Mendiagnosis masalah stabilitas

Jika mengalami masalah performa yang disebabkan oleh rekomposisi yang tidak perlu atau berlebihan, Anda harus men-debug stabilitas aplikasi. Panduan ini menjelaskan beberapa metode untuk melakukannya.

Layout Inspector

Layout Inspector di Android Studio memungkinkan Anda melihat composable mana yang melakukan rekomposisi di aplikasi. Layout ini menampilkan jumlah berapa kali Compose telah merekomposisi atau melewatkan komponen.

Jumlah rekomposisi dan lewati di Layout Inspector

Laporan compiler Compose

Compiler Compose dapat menampilkan hasil inferensi stabilitasnya untuk pemeriksaan. Dengan menggunakan output ini, Anda dapat menentukan composable mana yang dapat dilewati, dan mana yang tidak. Subbagian berikut meringkas cara menggunakan laporan ini, tetapi untuk informasi yang lebih mendetail, lihat dokumentasi teknis.

Penyiapan

Laporan compiler compiler tidak diaktifkan secara default. Anda dapat mengaktifkannya dengan flag compiler. Penyiapan yang tepat bervariasi bergantung pada project, tetapi untuk sebagian besar project, Anda dapat menempelkan skrip berikut ke file build.gradle root.

Groovy

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"
                )
            }
        }
    }
}

Menjalankan tugas

Untuk men-debug stabilitas composable, jalankan tugas sebagai berikut:

./gradlew assembleRelease -PcomposeCompilerReports=true

Contoh output

Tugas ini menghasilkan tiga file. Berikut adalah contoh output dari JetSnack.

  • <modulename>-classes.txt: Laporan tentang stabilitas class di modul ini. Contoh.
  • <modulename>-composables.txt: Laporan tentang cara composable dapat dimulai ulang dan dapat dilewati dalam modul. Contoh.
  • <modulename>-composables.csv:Versi CSV dari laporan composable yang dapat Anda impor ke spreadsheet atau pemrosesan menggunakan skrip. Contoh

Laporan composable

File composables.txt menjelaskan setiap fungsi composable untuk modul tertentu, termasuk stabilitas parameternya, dan apakah fungsi tersebut dapat dimulai ulang atau dapat dilewati. Berikut adalah contoh hipotesis dari 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
)

Composable SnackCollection ini dapat dimulai ulang sepenuhnya, dapat dilewati, dan stabil. Hal ini umumnya lebih disukai, meskipun tentu saja tidak wajib.

Di sisi lain, mari kita lihat contoh lain.

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
)

Composable HighlightedSnacks tidak dapat dilewati. Compose tidak pernah melewatinya selama rekomposisi. Hal ini terjadi meskipun tidak ada parameternya yang berubah. Alasannya adalah parameter unstable, snacks.

Laporan kelas

File classes.txt berisi laporan serupa tentang class dalam modul yang ditentukan. Cuplikan berikut adalah output untuk class 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
}

Sebagai referensi, berikut adalah definisi dari Snack:

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

Compiler Compose telah menandai Snack sebagai tidak stabil. Hal ini dikarenakan jenis parameter tags adalah Set<String>. Jenis ini tidak dapat diubah karena bukan MutableSet. Namun, class koleksi standar seperti Set, List, dan Map pada akhirnya adalah antarmuka. Oleh karena itu, implementasi yang mendasarinya mungkin masih dapat diubah.

Misalnya, Anda dapat menulis val set: Set<String> = mutableSetOf("foo"). Variabel bersifat konstan dan jenis yang dideklarasikan tidak dapat berubah, tetapi implementasinya masih dapat diubah. Compiler Compose tidak dapat memastikan ketetapan class ini karena hanya melihat jenis yang dideklarasikan. Oleh karena itu, fungsi ini menandai tags sebagai tidak stabil.