Güçlü atlama, Compose derleyicisinde kullanılabilen bir moddur. Etkinleştirildiğinde derleyicinin davranışını iki şekilde değiştirir:
- Kararsız parametreleri olan composable'lar atlanabilir olur.
- Kararsız yakalamalara sahip lambda'lar hatırlanır
Güçlü atlama modunu etkinleştirme
Güçlü atlama, Kotlin 2.0.20'de varsayılan olarak etkindir.
2.0.20'den önceki bir sürümde Gradle modülü için güçlü atlamayı etkinleştirmek istiyorsanız Gradle yapılandırmanızın composeCompiler bloğuna aşağıdaki seçeneği ekleyin:
android { ... }
composeCompiler {
enableStrongSkippingMode = true
}
Oluşturulabilir atlanabilirlik
Güçlü atlama modu, atlama ve composable işlevler söz konusu olduğunda Compose derleyicisi tarafından normalde uygulanan kararlılık kurallarından bazılarını esnetir. Varsayılan olarak, Compose derleyicisi tüm bağımsız değişkenleri kararlı değerlere sahipse bir composable işlevi atlanabilir olarak işaretler. Güçlü atlama modu bu durumu değiştirir.
Güçlü atlama etkinleştirildiğinde, yeniden başlatılabilir tüm composable işlevler atlanabilir hale gelir. Bu durum, kararsız parametreleri olup olmadığına bakılmaksızın geçerlidir. Yeniden başlatılamayan composable işlevler atlanamaz.
Ne zaman atlanmalı?
Compose, yeniden oluşturma sırasında bir composable'ın atlanıp atlanmayacağını belirlemek için her parametrenin değerini önceki değerleriyle karşılaştırır. Karşılaştırma türü, parametrenin kararlılığına bağlıdır.
- Kararsız parametreler, örnek eşitliği (
===) kullanılarak karşılaştırılır. - Kararlı parametreler, nesne eşitliği (
Object.equals()) kullanılarak karşılaştırılır.
Tüm parametreler bu koşulları karşılıyorsa Compose, yeniden oluşturma sırasında composable'ı atlar.
Bir composable'ın güçlü atlama özelliğini devre dışı bırakmasını isteyebilirsiniz. Yani yeniden başlatılabilir ancak atlanamayan bir composable isteyebilirsiniz. Bu durumda, @NonSkippableComposable ek açıklamasını kullanın.
@NonSkippableComposable
@Composable
fun MyNonSkippableComposable {}
Sınıfları kararlı olarak ek açıklama ekleme
Bir nesnenin örnek eşitliği (===) yerine nesne eşitliği (Object.equals()) kullanılarak karşılaştırılmasını istiyorsanız verilen sınıfı @Stable veya @Immutable ile ek açıklamalı olarak kullanmaya devam edin.
@Stable veya @Immutable eklemeden önce aşağıdaki avantaj ve dezavantajları göz önünde bulundurun:
- Oluşturma modüllerinde kararlı özelliklere sahip sınıflar zaten kararlıdır: Oluşturma derleyicisiyle derlenen bir modülde kararlı türlerin
valözelliklerine sahip bir sınıf, otomatik olarak kararlı olarak yorumlanır ve@Immutableveya@Stablegerekmeden.equals()kullanır. - Yalnızca ucuz
.equals()kontrolleri olan sınıflara ek açıklama ekleyin: Derleyici kararlılığı tahmin edemediğinde (ör. Compose olmayan modüllerdeki sınıflar) ve aynı değerlere sahip yeni örnekler sık sık tahsis edildiğinde@Stableveya@Immutableekleyin. Bu işlem, sınıfın.equals()kontrolünün ucuz olması koşuluyla yapılabilir. - Modelleri koleksiyonlarla ek açıklama eklerken dikkatli olun: Koleksiyon içeren modellere
@Stableveya@Immutableeklemek (ya daListyerineImmutableListkullanmak), Compose'un her yeniden oluşturma aşamasında koleksiyondaki her öğeyi.equals()ile karşılaştırmasına neden olur. Yavaş düzenlerde (LazyColumn,LazyRow,LazyGrid) kullanılan büyük koleksiyonlar veya modeller için her öğeyi karşılaştırmak, örnek eşitliği (===) kullanmaktan veya doğrudan yeniden oluşturmaktan daha yavaş olabilir.
Lambda memoization
Güçlü atlama modu, composable'ların içindeki lambda'ların daha fazla not edilmesini de sağlar. Güçlü atlama etkinleştirildiğinde, composable işlev içindeki her lambda otomatik olarak hatırlanır.
Örnekler
Güçlü atlama kullanılırken composable'ların içindeki lambda'ların memoization'ını sağlamak için derleyici, lambda'nızı bir remember çağrısıyla sarmalar. Lambda'nın yakalamalarıyla
anahtarlanır.
Aşağıdaki örnekte olduğu gibi bir lambda'nız olduğunu varsayalım:
@Composable
fun MyComposable(unstableObject: Unstable, stableObject: Stable) {
val lambda = {
use(unstableObject)
use(stableObject)
}
}
Güçlü atlama etkinleştirildiğinde derleyici, lambda'yı bir remember çağrısına sarmalayarak ezberler:
@Composable
fun MyComposable(unstableObject: Unstable, stableObject: Stable) {
val lambda = remember(unstableObject, stableObject) {
{
use(unstableObject)
use(stableObject)
}
}
}
Anahtarlar, composable işlevlerle aynı karşılaştırma kurallarına tabidir. Çalışma zamanı, kararsız anahtarları örnek eşitliğini kullanarak karşılaştırır. Kararlı anahtarları nesne eşitliğini kullanarak karşılaştırır.
Memoization and recomposition (Memoization ve yeniden oluşturma)
Bu optimizasyon, çalışma zamanının yeniden oluşturma sırasında atladığı composable sayısını önemli ölçüde artırır. Memoization kullanılmadığında, çalışma zamanının yeniden oluşturma sırasında lambda parametresi alan herhangi bir composable'a yeni bir lambda tahsis etme olasılığı çok daha yüksektir. Bu nedenle, yeni lambda'nın parametreleri son oluşturma ile aynı değildir. Bu durum, yeniden oluşturmaya neden olur.
Memoization'dan kaçınma
Memoize etmek istemediğiniz bir lambda varsa @DontMemoize ek açıklamasını kullanın.
val lambda = @DontMemoize {
...
}
APK Boyutu
Atlanabilir composable'lar derlendiğinde, atlanamayan composable'lara kıyasla daha fazla kod oluşturulur. Güçlü atlama etkinleştirildiğinde derleyici, neredeyse tüm composable'ları atlanabilir olarak işaretler ve tüm lambda'ları bir remember{...} içine sarmalar. Bu nedenle, güçlü atlama modunu etkinleştirmenin uygulamanızın APK boyutu üzerindeki etkisi çok azdır.
Now In Android'de güçlü atlamayı etkinleştirmek APK boyutunu 4 KB artırdı. Boyuttaki fark büyük ölçüde, söz konusu uygulamada bulunan ancak nispeten küçük olması gereken, daha önce atlanamayan composable'ların sayısına bağlıdır.