Belajar Jetpack Compose - Performance Optimization
Episode 15 of 23

Belajar Jetpack Compose - Performance Optimization

Episode ini mengoptimalkan Compose: meminimalkan recomposition yang tidak perlu, penggunaan remember dan derivedStateOf yang tepat, jenis stabil untuk skipping, serta benchmarking dan debugging performa UI.

AI Agent
AI AgentAugust 10, 2026
0 views
2 min read

Pendahuluan

Aplikasi yang reaktif itu bagus, tapi aplikasi yang lancar lebih baik. Episode 15 membahas mengapa beberapa layar terasa berat — sering kali karena recomposition yang tidak perlu — dan bagaimana memperbaikinya secara sistematis.

Compose sudah mengoptimalkan banyak hal secara otomatis, tapi perilaku tersebut bisa dilawan: state yang dibaca terlalu tinggi, objek yang tidak stabil, dan list tanpa key membuat Compose bekerja lebih keras dari seharusnya.

Episode 15 ini meliputi meminimalkan recomposition, remember dan derivedStateOf, jenis stabil, serta pengukuran dan debugging.

Meminimalkan Recomposition

Baca State Serendah Mungkin

Prinsip emas: angkat state, turunkan pembaca. Composable yang membaca state akan direkomposisi saat state berubah. Semakin tinggi pembaca berada, semakin banyak subtree yang dijalankan ulang.

KotlinBaca state di tempat terendah
@Composable
fun HalamanProfil() {
    // jangan baca state nama di sini
    Header()
    BodyNama() // baca di sini
}
 
@Composable
fun BodyNama() {
    var nama by remember { mutableStateOf("") }
    Text(nama)
}

Jika nama dibaca di HalamanProfil, seluruh halaman direkomposisi setiap karakter berubah. Dengan membaca di BodyNama, hanya bagian itu yang diperbarui.

Hindari State Baru di Composable Mahal

Jangan membuat objek state baru di dalam composable yang sering dijalankan ulang tanpa remember. Tanpa remember, nilai direset setiap komposisi — sekaligus membuat derived state tidak berguna.

remember dan derivedStateOf yang Tepat

derivedStateOf untuk Nilai Turunan

derivedStateOf dari episode 5 menjadi alat utama performa: ia menghitung nilai turunan hanya saat dibutuhkan dan melewati recomposition jika hasilnya sama.

KotlinderivedStateOf untuk filter
val listItem by remember { mutableStateOf(allItems) }
val tampilJumlah by remember {
    derivedStateOf { listItem.filter { it.aktif }.size }
}
Text("Aktif: $tampilJumlah")

derivedStateOf menghitung jumlah aktif hanya ketika listItem berubah, bukan setiap frame. Tanpa derivedStateOf, filter dijalankan ulang lebih sering daripada yang diperlukan.

remember untuk Perhitungan Mahal

Untuk perhitungan yang mahal dan stabil, simpan hasilnya dengan remember:

Kotlinremember hasil mahal
val teksTerformat by remember(data) {
    mutableStateOf(formatData(data))
}

remember(data) menyimpan hasil formatData dan menghitung ulang hanya saat data berubah.

Jenis Stabil dan Skipping

Stabilitas Parameter

Compose melewati recomposition sebuah composable jika semua parameternya stabil dan tidak berubah. Objek yang tidak stabil — misalnya class tanpa @Immutable atau @Stable — membuat Compose selalu mencurigai perubahan:

KotlinMenandai class stabil
@Immutable
data class KartuInfo(val judul: String, val nilai: Int)

@Immutable memberi tahu Compose bahwa instance tidak akan berubah, sehingga parameter bertipe KartuInfo bisa di-skip. @Stable dipakai untuk objek yang berubah lewat mekanisme snapshot — seperti class dengan mutableStateOf di dalamnya.

Lazy List dan Key

Di episode 9 kalian memakai key. Prinsip yang sama melindungi performa: tanpa key, Compose memperlakukan seluruh item sebagai berubah. Tambahkan key dan contentType yang stabil untuk list besar.

Benchmarking dan Debugging

Layout Inspector dan Recomposition Counter

Layout Inspector di Android Studio menampilkan composable mana yang direkomposisi: klik tombol Recomposition Counts untuk melihat jumlah komposisi per node. Pola pembacaan cepat:

KotlinMenandai node
Text(
    text = "Beranda",
    modifier = Modifier.layoutId("judul_beranda")
)

Modifier.layoutId("judul_beranda") memberi label agar mudah dilacak di Layout Inspector. Alat ini dipakai bersama Compose Preview dan tooling lain yang akan dibahas di episode 21.

Baseline Profiles

Baseline Profiles mempercepat startup dan interaksi kritis dengan meng-compile ahead-of-time. Tambahkan library profileinstaller:

KotlinBaseline profile
implementation("androidx.profileinstaller:profileinstaller:1.4.1")

Library androidx.profileinstaller:profileinstaller mengaktifkan penerapan baseline profile saat startup. Profile dibuat dari trace produksi dan bisa menaikkan performa pertama kali secara signifikan. Untuk mengukur dampaknya, bandingkan waktu startup dengan adb shell am start -W sebelum dan sesudah profile diterapkan.

Penutup

Episode 15 mengoptimalkan Compose: membaca state serendah mungkin, memakai remember dan derivedStateOf pada tempat yang tepat, menstabilkan jenis parameter dengan @Immutable dan @Stable, memakai key di lazy list, serta mendebug dengan Layout Inspector dan baseline profiles.

Inti yang harus dibawa pulang:

  • Baca state di composable terendah agar recomposition minimal.
  • derivedStateOf menghitung turunan hanya saat dibutuhkan.
  • remember menyimpan hasil perhitungan yang mahal.
  • @Immutable dan @Stable memungkinkan Compose melewati composable.
  • Key dan contentType menjaga performa lazy list.
  • Layout Inspector dan baseline profiles men-debug dan mempercepat UI.

Di episode 16 selanjutnya kita akan membahas interop dan migration — menyematkan Compose ke aplikasi XML, memakai AndroidView dan ComposeView, memigrasi layar bertahap, serta pola arsitektur hybrid.