Oluşturulmada Kararlılık

Compose, türleri kararlı veya kararsız olarak kabul eder. Bir tür, sabitse veya Compose'un, değerinin yeniden oluşturmalar arasında değişip değişmediğini bilmesi mümkünse kararlıdır. Compose, yeniden oluşturmalar arasında değerinin değişip değişmediğini belirleyemiyorsa tür kararsızdır.

Compose, girişleri nasıl karşılaştıracağını belirlemek ve yeniden oluşturma sırasında (Kotlin 2.0.20'den itibaren varsayılan olarak etkinleştirilen güçlü atlama modu ile) composable'ı atlayıp atlayamayacağına karar vermek için composable parametrelerinin kararlılığını kullanır:

  • Kararlı parametreler: Compose, kararlı parametreleri yapısal eşitlik (Object.equals()) kullanarak karşılaştırır. Bir composable'ın kararlı parametreleri önceki değerlerine eşitse Compose bu parametreyi atlar.
  • Kararsız parametreler: Güçlü atlama modu etkinleştirildiğinde (Kotlin 2.0.20 ve sonraki sürümlerde varsayılan) Compose, kararsız parametreleri örnek eşitliği (===) kullanarak karşılaştırır ve aynı nesne örnekleri iletilirse composable'ı atlar. Kotlin 2.0.20'den önceki sürümlerde (veya güçlü atlama modu devre dışı bırakıldığında) Compose, üst öğesi yeniden oluşturulduğunda kararsız parametreleri olan bir composable'ı her zaman yeniden oluşturur.

Uygulamanız sık sık kararsız parametrelerin yeni örneklerini tahsis ediyorsa veya modellere aşırı ek açıklama ekleyerek büyük koleksiyonlarda pahalı .equals() kontrollerini zorunlu kılıyorsa gereksiz yeniden oluşturma işlemleri veya karşılaştırma ek yükü görebilirsiniz.

Bu belgede, Compose'un kararlılığı nasıl belirlediği ve performansı ve genel kullanıcı deneyimini iyileştirmek için nasıl optimize edebileceğiniz ayrıntılı olarak açıklanmaktadır.

Değiştirilemez nesneler

Aşağıdaki snippet'ler, kararlılık ve yeniden oluşturmanın ardındaki genel ilkeleri göstermektedir.

Contact sınıfı, sabit bir veri sınıfıdır. Bunun nedeni, tüm parametrelerinin val anahtar kelimesiyle tanımlanan temel öğeler olmasıdır. Bir Contact örneği oluşturduktan sonra nesnenin özelliklerinin değerini değiştiremezsiniz. Bunu yapmaya çalışırsanız yeni bir nesne oluşturursunuz.

data class Contact(val name: String, val number: String)

ContactRow composable'ının Contact türünde bir parametresi var.

@Composable
fun ContactRow(contact: Contact, modifier: Modifier = Modifier) {
   var selected by remember { mutableStateOf(false) }

   Row(modifier) {
      ContactDetails(contact)
      ToggleButton(selected, onToggled = { selected = !selected })
   }
}

Kullanıcı açma/kapatma düğmesini tıkladığında ve durum değiştiğinde ne olacağını düşünün: selected

  1. Compose, ContactRow içindeki kodu yeniden oluşturması gerekip gerekmediğini değerlendirir.
  2. ContactDetails için tek bağımsız değişkenin Contact türünde olduğunu görür.
  3. Contact, sabit bir veri sınıfı olduğundan Compose, ContactDetails bağımsız değişkenlerinden hiçbirinin değişmediğinden emin olur.
  4. Bu nedenle, Compose ContactDetails öğesini atlar ve yeniden oluşturmaz.
  5. Öte yandan, ToggleButton için bağımsız değişkenler değişti ve Compose bu bileşeni yeniden oluşturur.

Değiştirilebilir nesneler

Önceki örnekte sabit bir nesne kullanılmış olsa da değiştirilebilir bir nesne oluşturmak da mümkündür. Aşağıdaki snippet'i inceleyin:

data class Contact(var name: String, var number: String)

Contact sınıfının her parametresi artık var olduğundan sınıf artık sabit değildir. Özellikleri değişirse Compose bunu fark etmez. Bunun nedeni, Compose'un yalnızca Compose State nesnelerindeki değişiklikleri izlemesidir.

Compose, bu tür sınıfları kararsız olarak kabul eder. Güçlü atlama modu (Kotlin 2.0.20+) ile Compose, örnek eşitliğini (===) kullanarak Contact değerini karşılaştırır: contact.name değerini yerinde değiştirmek yeniden oluşturmayı tetiklemez ancak aynı değerlere sahip yeni ayrılmış bir Contact örneği iletmek ContactDetails öğesini yeniden oluşturmaya zorlar (ve güçlü atlama modu olmadan ContactDetails, selected her değiştiğinde yeniden oluşturulur).

Compose'da uygulama

Oluşturma'nın yeniden oluşturma sırasında hangi işlevleri atlayacağını tam olarak nasıl belirlediğini düşünmek faydalı olabilir ancak çok önemli değildir.

Compose derleyici, kodunuzu çalıştırdığında her işlevi ve türü birkaç etiketten biriyle işaretler. Bu etiketler, Compose'un yeniden oluşturma sırasında işlevi veya türü nasıl işlediğini gösterir.

İşlevler

Compose, işlevleri skippable veya restartable olarak işaretleyebilir. Bir işlevi bunlardan biri, her ikisi veya hiçbiri olarak işaretleyebileceğini unutmayın:

  • Atlanabilir: Derleyici, bir composable'ı atlanabilir olarak işaretlerse Compose, tüm bağımsız değişkenleri önceki değerleriyle eşitse yeniden oluşturma sırasında bu composable'ı atlayabilir. (Kotlin 2.0.20 ve sonraki sürümlerde güçlü atlama modu ile yeniden başlatılabilir tüm composable'lar otomatik olarak atlanabilir.)
  • Yeniden başlatılabilir: Yeniden başlatılabilir bir composable, yeniden oluşturmanın başlayabileceği bir "kapsam" görevi görür. Başka bir deyişle işlev, durum değişikliklerinden sonra Compose'un yeniden oluşturma için kodu yeniden yürütmeye başlayabileceği bir giriş noktası olabilir.

Türler

Compose, türleri sabit veya kararlı olarak işaretler. Her tür, aşağıdakilerden biridir:

  • Değiştirilemez: Özelliklerinin değeri hiçbir zaman değişemiyorsa ve tüm yöntemler referans açısından şeffafsa Compose, bir türü değiştirilemez olarak işaretler.
    • Tüm temel türlerin değişmez olarak işaretlendiğini unutmayın. Bunlar arasında String, Int ve Float yer alır.
  • Kararlı: Özellikleri oluşturulduktan sonra değişebilen bir türü belirtir. Bu özellikler çalışma zamanında değişirse Compose bu değişiklikleri algılar.

Hata ayıklama kararlılığı

Uygulamanız, parametreleri değişmemiş bir composable'ı yeniden oluşturuyorsa öncelikle her yeniden oluşturma işleminde kararsız türlerin yeni örneklerinin tahsis edilip edilmediğini kontrol edin (veya güçlü atlama modu devre dışıysa composable'ın kararsız bir türün var özelliklerine veya val özelliklerine sahip parametreleri olup olmadığını kontrol edin).

Compose'da kararlılıkla ilgili karmaşık sorunları teşhis etme hakkında ayrıntılı bilgi için Kararlılıkta hata ayıklama kılavuzunu inceleyin.

Kararlılık sorunlarını düzeltme

Compose uygulamanızı nasıl kararlı hale getireceğiniz hakkında bilgi için Kararlılık sorunlarını düzeltme kılavuzunu inceleyin.

Özet

Genel olarak aşağıdaki noktalara dikkat etmeniz gerekir:

  • Parametreler: Compose, yeniden oluşturma sırasında yapısal eşitlik (.equals()) veya örnek eşitliği (===) kullanarak karşılaştırma yapıp yapmayacağına karar vermek için composable'larınızın her bir parametresinin kararlılığını belirler.
  • Anında düzeltmeler: Oluşturulabilir öğenizin atlanmadığını ve performans sorununa neden olduğunu fark ederseniz her geçişte kararsız parametrelerin yeni örneklerinin yeniden oluşturulup oluşturulmadığını veya State yerine var özelliklerinin kullanılıp kullanılmadığını kontrol edin.
  • Derleyici raporları: Sınıflarınız hakkında hangi kararlılığın tahmin edildiğini belirlemek için derleyici raporlarını kullanabilirsiniz.
  • Koleksiyonlar: Compose, standart koleksiyon arayüzlerini (List, Set ve Map) kararsız olarak kabul eder çünkü temel uygulamaları değiştirilebilir olabilir. Güçlü atlama modu (Kotlin 2.0.20 ve sonraki sürümlerde varsayılan olarak etkindir) sayesinde, kararsız koleksiyonlar, koleksiyon referansı değişmediğinde örnek eşitliğini (===) kullanarak yeniden oluşturmayı atlamaya devam eder. Standart koleksiyonları Kotlinx sabit koleksiyonları ile değiştirirken veya koleksiyon içeren sınıflara @Immutable ya da @Stable ile ek açıklama eklerken dikkatli olun. Her yeniden oluşturma aşamasında her öğeyi .equals() ile karşılaştırmak, yeniden oluşturma işleminden daha maliyetli olabilir.
  • Diğer modüller: Compose, Compose derleyicisinin çalışmadığı modüllerdeki sınıfları kararsız olarak kabul eder (Güçlü atlama modunda === kullanılarak karşılaştırılır). Bir veri kaynağı, Compose dışı modüllerden aynı değerlere sahip küçük, düz modelleri sık sık yeniden örneklendiriyorsa bir kararlılık yapılandırma dosyası yapılandırabilir veya .equals()'nin ucuz olduğu yerlerde @Stable ya da @Immutable kullanabilirsiniz.

Daha fazla bilgi