Compose menganggap jenis sebagai stabil atau tidak stabil. Suatu jenis dikatakan stabil jika tidak dapat diubah, atau jika Compose dapat mengetahui apakah nilainya telah berubah saat rekomposisi. Suatu jenis dikatakan tidak stabil jika Compose tidak dapat mengetahui apakah nilainya telah berubah saat rekomposisi.
Compose menggunakan stabilitas parameter composable untuk menentukan cara membandingkan input dan memutuskan apakah composable dapat melewati rekomposisi (dengan Mode skipping kuat diaktifkan secara default mulai di Kotlin 2.0.20):
- Parameter stabil: Compose membandingkan parameter stabil menggunakan persamaan
struktural (
Object.equals()). Jika parameter stabil composable sama dengan nilai sebelumnya, Compose akan melewatinya. - Parameter tidak stabil: Dengan Mode skipping kuat diaktifkan (default di Kotlin 2.0.20 dan yang lebih tinggi), Compose membandingkan parameter tidak stabil menggunakan persamaan instance (
===) dan melewati composable jika instance objek yang sama diteruskan. Pada versi sebelum Kotlin 2.0.20 (atau saat mode skipping kuat dinonaktifkan), Compose selalu merekomposisi composable dengan parameter tidak stabil saat induknya merekomposisi.
Jika aplikasi Anda sering mengalokasikan instance baru dari parameter yang tidak stabil—atau memaksakan pemeriksaan .equals() yang mahal pada koleksi besar dengan menganotasi model secara berlebihan—Anda mungkin mengamati rekomposisi yang tidak perlu atau overhead perbandingan.
Dokumen ini menjelaskan secara mendetail cara Compose menentukan stabilitas dan cara Anda dapat mengoptimalkannya untuk meningkatkan performa dan pengalaman pengguna secara keseluruhan.
Objek yang tidak dapat diubah
Cuplikan berikut menunjukkan prinsip umum di balik stabilitas dan rekomposisi.
Class Contact adalah class data yang tidak dapat diubah. Hal ini karena semua
parameternya adalah primitif yang ditentukan dengan kata kunci val. Setelah membuat instance
Contact, Anda tidak dapat mengubah nilai properti objek.
Jika Anda mencoba melakukannya, Anda akan membuat objek baru.
data class Contact(val name: String, val number: String)
Composable ContactRow memiliki parameter jenis Contact.
@Composable
fun ContactRow(contact: Contact, modifier: Modifier = Modifier) {
var selected by remember { mutableStateOf(false) }
Row(modifier) {
ContactDetails(contact)
ToggleButton(selected, onToggled = { selected = !selected })
}
}
Pertimbangkan apa yang terjadi saat pengguna mengklik tombol pengalih dan status selected berubah:
- Compose mengevaluasi apakah harus merekomposisi kode di dalam
ContactRow. - Model melihat bahwa satu-satunya argumen untuk
ContactDetailsadalah jenisContact. - Karena
Contactadalah class data yang tidak dapat diubah, Compose yakin bahwa tidak ada argumen untukContactDetailsyang berubah. - Oleh karena itu, Compose melewati
ContactDetailsdan tidak merekomposisinya. - Di sisi lain, argumen untuk
ToggleButtontelah berubah, dan Compose merekomposisi komponen tersebut.
Objek yang dapat berubah
Meskipun contoh sebelumnya menggunakan objek yang tidak dapat diubah, Anda dapat membuat objek yang dapat diubah. Pertimbangkan cuplikan berikut:
data class Contact(var name: String, var number: String)
Karena setiap parameter Contact kini berupa var, class tidak lagi tidak dapat diubah.
Jika propertinya berubah, Compose tidak akan mengetahuinya. Hal ini karena
Compose hanya melacak perubahan pada objek Status Compose.
Compose menganggap class tersebut tidak stabil. Dengan Mode lewati kuat
(Kotlin 2.0.20+), Compose membandingkan Contact menggunakan kesamaan instance (===):
memutasi contact.name di tempat tidak akan memicu rekomposisi, sementara meneruskan
instance Contact yang baru dialokasikan dengan nilai yang identik akan tetap memaksa
ContactDetails untuk merekomposisi (dan tanpa Mode lewati kuat,
ContactDetails merekomposisi setiap kali selected berubah).
Implementasi di Compose
Meskipun tidak penting, ada baiknya untuk mempertimbangkan secara tepat cara Compose menentukan fungsi mana yang akan dilewati selama rekomposisi.
Saat compiler Compose berjalan di kode Anda, compiler akan menandai setiap fungsi dan jenis dengan salah satu dari beberapa tag. Tag ini mencerminkan cara Compose menangani fungsi atau jenis selama rekomposisi.
Fungsi
Compose dapat menandai fungsi sebagai skippable atau restartable. Perhatikan bahwa fungsi ini dapat menandai fungsi sebagai salah satu, keduanya, atau tidak satu pun dari hal berikut:
- Dapat dilewati: Jika compiler menandai composable sebagai dapat dilewati, Compose dapat melewatinya selama rekomposisi jika semua argumennya sama dengan nilai sebelumnya. (Dengan Mode skipping kuat di Kotlin 2.0.20+, semua composable yang dapat dimulai ulang otomatis dapat dilewati.)
- Dapat dimulai ulang: Composable yang dapat dimulai ulang berfungsi sebagai "cakupan" tempat rekomposisi dapat dimulai. Dengan kata lain, fungsi dapat menjadi titik entri tempat Compose dapat mulai mengeksekusi ulang kode untuk rekomposisi setelah perubahan status.
Jenis
Compose menandai jenis sebagai tidak dapat diubah atau stabil. Setiap jenis adalah salah satu dari berikut:
- Tidak dapat diubah: Compose menandai jenis sebagai tidak dapat diubah jika nilai propertinya tidak pernah berubah dan semua metodenya transparan secara referensial.
- Perhatikan bahwa semua jenis primitif ditandai sebagai tidak dapat diubah. Hal ini mencakup
String,Int, danFloat.
- Perhatikan bahwa semua jenis primitif ditandai sebagai tidak dapat diubah. Hal ini mencakup
- Stabil: Menunjukkan jenis yang propertinya dapat berubah setelah konstruksi. Jika dan saat properti tersebut berubah selama runtime, Compose akan mengetahui perubahan tersebut.
Stabilitas debug
Jika aplikasi Anda merekomposisi composable yang parameternya tidak berubah, pertama-tama
periksa apakah instance baru dari jenis yang tidak stabil dialokasikan pada setiap
rekomposisi (atau, jika mode skipping Kuat dinonaktifkan, apakah composable
memiliki parameter dengan properti var atau properti val dari jenis yang tidak stabil).
Untuk mengetahui informasi mendetail tentang cara mendiagnosis masalah kompleks terkait stabilitas di Compose, lihat panduan Men-debug stabilitas.
Memperbaiki masalah stabilitas
Untuk mengetahui informasi tentang cara menstabilkan penerapan Compose, lihat panduan Memperbaiki masalah stabilitas.
Ringkasan
Secara keseluruhan, Anda harus memperhatikan poin-poin berikut:
- Parameter: Compose menentukan stabilitas setiap parameter composable Anda untuk memutuskan apakah akan membandingkannya menggunakan persamaan struktural (
.equals()) atau persamaan instance (===) selama rekomposisi. - Perbaikan langsung: Jika Anda melihat composable tidak dilewati dan
menyebabkan masalah performa, periksa apakah instance baru parameter yang tidak stabil
dibuat ulang pada setiap penerusan atau apakah properti
varsedang digunakan, bukanState. - Laporan compiler: Anda dapat menggunakan laporan compiler untuk menentukan stabilitas yang disimpulkan tentang class Anda.
- Koleksi: Compose menganggap antarmuka koleksi standar (
List,Set, danMap) tidak stabil karena implementasi yang mendasarinya dapat berubah. Dengan Mode lewati kuat (diaktifkan secara default di Kotlin 2.0.20+), koleksi yang tidak stabil tetap melewati rekomposisi menggunakan kesamaan instanceO(1)cepat (===) saat referensi koleksi tidak berubah. Hindari mengonversi koleksi besar ke Koleksi imutable Kotlinx atau mengannotasi class yang menyimpan koleksi dengan@Immutableatau@Stablekecuali persamaan struktural (O(N).equals()) secara khusus diperlukan, karena membandingkan setiap elemen pada setiap rekomposisi dapat lebih mahal daripada rekomposisi itu sendiri. - Modul lain: Compose menganggap class dari modul tempat compiler Compose tidak berjalan sebagai tidak stabil (dibandingkan menggunakan
===dalam mode skipping Kuat). Jika sumber data sering membuat ulang model kecil dan datar dari modul non-Compose dengan nilai yang identik, Anda dapat mengonfigurasi file konfigurasi stabilitas atau menggunakan@Stableatau@Immutablejika.equals()murah.
Bacaan lebih lanjut
- Performa: Untuk tips penelusuran bug selengkapnya tentang performa Compose, lihat panduan praktik terbaik dan video I/O kami.