Yeniden Oluşturmayı Denetleme
Kararlı parametreler kullanın ve yeniden oluşturmaları azaltın.
Yeniden Oluşturmayı Denetleme, CoddyKit'te ücretsiz bir Android Academy dersidir. Bu, 4 dersinin 2. dersidir. Aşağıdan dersin tamamını ücretsiz okuyabilir, sonra tarayıcıda yerleşik kod editörü ve 7/24 yapay zeka koçu ile uygulamalı olarak pratik yapabilirsin. Bu, Android Academy öğrenme yolunun bir parçasıdır ve ilerlemeniz web ve CoddyKit uygulaması arasında senkronize olur. Android Academy kursu toplamda 4 dersten oluşur.
Yeniden Oluşturma: Compose Performans Ayarı
Jetpack Compose'da kullanıcı arayüzü işlevlerle tanımlanır. Durum değiştiğinde Compose yeniden oluşturma yapar: ekranı güncellemek için o durumu okuyan oluşturulabilir işlevleri yeniden çalıştırır.
Yeniden oluşturma, kapsamı iyi belirlendiğinde normal ve ucuzdur. Ancak çok sık gerçekleştiğinde veya ağacın çok büyük bir bölümünü kapsadığında Compose takılmalarının bir numaralı nedeni olur. Bu ders, yeniden oluşturmayı küçük ve seyrek tutmayı öğretir.
Yeniden Oluşturma Sayılarını Görme
Düzeltmeden önce ölçün. Android Studio'daki Yerleşim Denetleyicisi, her oluşturulabilir işlev için yeniden oluşturma sayılarını gerçek zamanlı gösterir. Ayrıca Compose derleyicisinin ölçümlerini veya hızlı bir hata ayıklama sayacını da kullanabilirsiniz.
Basit bir yöntem şudur: SideEffect, oluşturulabilir bir işlev her yeniden oluşturulduğunda bir başvuruyu artırır; böylece geliştirme sırasında beklenmedik durumları günlüğe kaydedebilirsiniz.
@Composable
fun RecompositionCounter(tag: String) {
val count = remember { mutableStateOf(0) }
SideEffect { count.value++ }
Log.d("Recompose", "$tag recomposed ${count.value} times")
}
// Drop RecompositionCounter("PriceLabel") inside a composable
// to watch how often it re-runs while you interact.Durumu Mümkün Olduğunca Geç Okuyun
Compose yalnızca bir durum değerini okuyan oluşturulabilir işlevleri yeniden oluşturur. Bir üst öğe durumu okursa üst öğenin tamamı yeniden oluşturulur; yalnızca küçük bir alt öğe okursa yalnızca o alt öğe yeniden oluşturulur.
Bu nedenle durum okumalarını ağaçta aşağıya taşıyın. Buradaki kötü sürüm, her tikte tüm Column'u yeniden oluşturur; iyi sürüm ise işlemi etiketle sınırlar.
// BAD: Column reads `seconds`, so everything recomposes each second
@Composable
fun TimerBad(seconds: Int) {
Column {
ExpensiveHeader()
Text("Elapsed: $seconds")
}
}
// GOOD: only the Text reads the value via a lambda
@Composable
fun TimerGood(seconds: () -> Int) {
Column {
ExpensiveHeader()
Text("Elapsed: ${seconds()}")
}
}Lambda'larla Okumaları Erteleyin
Güçlü bir kalıp şudur: sık değişen bir değeri geçirmek yerine, bu değeri döndüren bir lambda geçirin. Lambda'yı sonunda çağıran oluşturulabilir işlev, yeniden oluşturulan tek işlev olur.
Modifier.offset { ... } ve graphicsLayer { ... } işlevlerinin lambda almasının nedeni budur: kaydırma ve animasyon değerleri her karede değişir; lambda, yeniden oluşturmayı yerleşim aşamasından tamamen uzak tutar.
// Passing the value: parent recomposes every frame of scroll
Box(Modifier.offset(y = scrollOffset.dp))
// Passing a lambda: skips recomposition, updates in the layout phase
Box(Modifier.offset { IntOffset(x = 0, y = scrollOffset.roundToInt()) })
// Same idea for alpha/scale during animation:
Image(
painter = painter,
contentDescription = null,
modifier = Modifier.graphicsLayer { alpha = animatedAlpha() }
)Kararlılık: Compose Neden Atlayabilir
Tüm parametreleri kararlı ve değişmemişse Compose, bir oluşturulabilir işlevin yeniden oluşturulmasını atlayabilir. Bir tür, Compose equals işlevinin gerçek değişikliği yansıttığına ve herkese açık alanlarının fark edilmeden değişmediğine güvenebildiğinde kararlıdır.
- Kararlı: ilkel türler,
String, değişmez veri sınıfları,State. - Kararsız:
List/Maparayüzleri,varalanlarına sahip sınıflar, derleyicinin bulunmadığı modüllerdeki türler.
Kararsız bir parametre, hiçbir şey değişmemiş olsa bile yeniden oluşturmayı zorunlu kılar.
// UNSTABLE: List is an interface; Compose cannot assume immutability,
// so UserList recomposes even if the contents are identical.
@Composable
fun UserList(users: List<User>) { /* ... */ }
data class User(val id: Long, val name: String) // stable: all valsParametreleri Kararlı Hale Getirin
Kararsız parametreler için iki yaygın çözüm vardır:
- Compose'un kararlı kabul ettiği
kotlinx.collections.immutableiçindeki değişmez koleksiyonları (ör.ImmutableList) kullanın. - Denetiminizdeki bir sınıfa, değişmeyeceğini Compose'a bildirmek için
@Immutableveya@Stableek açıklamasını uygulayın.
Artık aynı örnek yeniden geçirildiğinde Compose yeniden oluşturmayı güvenle atlayabilir.
import kotlinx.collections.immutable.ImmutableList
import androidx.compose.runtime.Immutable
@Immutable
data class UiState(
val title: String,
val users: ImmutableList<User>
)
// Stable parameter -> Compose can skip this when state is unchanged
@Composable
fun UserList(users: ImmutableList<User>) { /* ... */ }remember: Her Karede Yeniden Hesaplamayın
Oluşturulabilir işlevler birçok kez çalışabilir. Gövdede doğrudan yapılan önemsiz olmayan her hesaplama her yeniden oluşturmada çalışır. Yalnızca anahtarları değiştiğinde yeniden hesaplanması için bunu remember ile sarın.
Diğer durumlardan türetilen değerler için, yalnızca hesaplanan sonuç gerçekten değiştiğinde yeniden yayın yapan derivedStateOf işlevini tercih edin.
// Recomputes the sorted list only when `items` changes
val sorted = remember(items) { items.sortedBy { it.name } }
// derivedStateOf: only triggers readers when the BOOLEAN flips,
// not on every scroll pixel
val showButton by remember {
derivedStateOf { listState.firstVisibleItemIndex > 5 }
}
if (showButton) ScrollToTopButton()Tembel Listelerde Kararlı Anahtarlar
LazyColumn/LazyRow içinde her öğeye kararlı bir anahtar verin. Anahtarlar olmadığında, Compose öğeleri konumlarına göre izlediği için öğe eklemek veya sıralamayı değiştirmek, aslında değişmemiş öğelerin yeniden oluşturulup yeniden ölçülmesine neden olur.
Kararlı bir anahtarla Compose, güncellemeler arasındaki öğeleri eşleştirebilir ve değişmemiş olanları atlayabilir.
LazyColumn {
items(
items = users,
key = { user -> user.id } // stable identity
) { user ->
UserRow(user)
}
}
// Now adding a user at the top reuses existing rows
// instead of recomposing the whole list.Durumu Üst Seviyeye Taşıyın, Olayları Yukarı Gönderin
Kararsız lambda parametreleri, her yeniden oluşturmada yeni bir lambda örneği oluşturulursa atlamayı da bozabilir. Geri çağırmaları hatırlayarak veya kararlı işlevlere başvurarak kararlı hale getirin.
Durumun üst seviyeye taşınmasıyla (durum çağıranda yaşar, olaylar yukarı akar) birlikte bu yaklaşım, yaprak oluşturulabilir işlevleri ucuz ve atlanabilir tutar.
@Composable
fun SearchBar(query: String, onQueryChange: (String) -> Unit) {
TextField(value = query, onValueChange = onQueryChange)
}
// In the caller, a remembered lambda keeps the reference stable:
val onChange = remember { { newValue: String -> viewModel.setQuery(newValue) } }
SearchBar(query = query, onQueryChange = onChange)Kaydırma/Animasyon Durumunu Çok Üst Seviyede Okumaktan Kaçının
Klasik bir hata, hızlı değişen bir durumu (kaydırma uzaklığı, animasyon ilerlemesi) üst düzey bir oluşturulabilir işlevde okumaktır. Bu, tüm alt ağacın her karede yeniden oluşturulmasına neden olur.
Bu tür okumaları Modifier lambda'larının (offset {}, graphicsLayer {}, drawBehind {}) içinde tutun; böylece çalışma yeniden oluşturma yerine yerleşim veya çizim aşamasında gerçekleşir. Akıcı 60 kare/sn kaydırma ile takılmalı kaydırma arasındaki fark budur.
// Animated color used only for drawing -> stay in the draw phase
Box(
Modifier.drawBehind {
drawRect(color = animatedColor()) // lambda read, no recomposition
}
)Yeniden Oluşturma Kontrol Listesi
Bir ekran etkileşim sırasında takılıyormuş gibi hissettirdiğinde bu listeyi gözden geçirin:
- Parametreler kararlı mı (değişmez veriler,
ImmutableList)? - Hızlı değişen durumu mümkün olduğunca alt seviyede, ideal olarak değiştirici lambda'larında mı okuyorsunuz?
- Tembel listelerde kararlı anahtarlar var mı?
- Pahalı hesaplamalar
remember/derivedStateOfarkasında mı? - Yerleşim Denetleyicisi sayının gerçekten azaldığını doğruladı mı?
İşaretlediğiniz her kutu, her karedeki gereksiz çalışmayı ortadan kaldırır.
Hızlı Kontrol
Bir oluşturulabilir işleve List<User> geçiriyor ve veri değişmemiş olsa bile yeniden oluşturulduğunu fark ediyorsunuz. En doğrudan çözüm nedir?
Özet: Daha Küçük, Daha Seyrek Yeniden Oluşturma
Compose'un en önemli performans sorunlarından biri olan yeniden oluşturmayı kontrol altına almayı öğrendiniz:
- Yerleşim Denetleyicisi veya hata ayıklama sayacıyla sayıları ölçün.
- Durumu mümkün olduğunca alt seviyede okuyun; okumaları lambda'larla erteleyin.
- Değişmez veriler ve
@Immutable/ImmutableListile parametreleri kararlı hale getirin. - Her karede yeniden hesaplamayı önlemek için
remembervederivedStateOfkullanın. - Tembel öğelere kararlı anahtarlar verin; hızlı durum okumalarını değiştirici lambda'larında tutun.
Sırada CPU/yeniden oluşturmadan belleğe geçiyor, sızıntıları bulup düzeltiyoruz.
Sıkça Sorulan Sorular
“Yeniden Oluşturmayı Denetleme” dersi ücretsiz mi?
Evet — “Yeniden Oluşturmayı Denetleme” dersin tüm metni burada web'de ücretsiz olarak okunabilir. Etkileşimli olarak pratik yapmak (yerleşik kod editörü ve 7/24 yapay zeka koçu) ve Android Academy kursunun geri kalanını açmak için CoddyKit PRO'ya yükselt. Android Academy kursu toplamda 4 dersten oluşur.
“Yeniden Oluşturmayı Denetleme” dersinde ne öğreneceğim?
Kararlı parametreler kullanın ve yeniden oluşturmaları azaltın. Android Academy ile uygulamalı kodu tarayıcıda doğrudan çalıştırarak pratik yaparsın ve 7/24 yapay zeka koçu dersi çalışırken sorularını yanıtlar.
Android Academy öğrenmeye başlamak için deneyim gerekli mi?
Önceden deneyim gerekmez. CoddyKit'te Android Academy, başlangıçtan ileri seviyeye kadar yapılandırıldığı için buradan başlayabilir veya başından başlayıp kendi hızında ilerleme yapabilirsin. Bu, 4 dersinin 2. dersidir.
“Yeniden Oluşturmayı Denetleme” dersi ne kadar sürer?
Çoğu CoddyKit dersi yaklaşık 5–10 dakika sürer. Her biri kısa ve etkileşimli olduğu için sabit ilerleme yaparsın ve web ile uygulama arasında tam olarak bıraktığın yerden devam edebilirsin.
Bu Android Academy dersinde kod yazıp çalıştırabilir miyim?
Evet. Her Android Academy dersi yerleşik bir kod editörü içerir, bu sayede tarayıcıda gerçek kod yazıp çalıştırabilir ve anlık yapay zeka geri bildirimi alırsın — yerel kurulum gerekli değildir.
Bu kursun tüm dersleri
- Performansı Ölçme
- Yeniden Oluşturmayı Denetleme
- Bellek Sızıntıları ve Çözümleri
- Başlangıç ve Temel Profiller