Mode lewati yang kuat

Strong Skipping adalah mode yang tersedia di compiler Compose. Jika diaktifkan, fitur ini akan mengubah perilaku compiler dengan dua cara:

  • Composable dengan parameter tidak stabil menjadi dapat dilewati
  • Lambda dengan pengambilan yang tidak stabil akan diingat

Mengaktifkan mode skipping kuat

Mode skipping kuat diaktifkan secara default di Kotlin 2.0.20.

Untuk mengaktifkan mode strong skipping untuk modul Gradle dalam rilis sebelum 2.0.20, sertakan opsi berikut dalam blok composeCompiler konfigurasi Gradle Anda:

android { ... }

composeCompiler {
   enableStrongSkippingMode = true
}

Kemampuan composable untuk dilewati

Mode strong skipping melonggarkan beberapa aturan stabilitas yang biasanya diterapkan oleh compiler Compose dalam hal fungsi composable dan fungsi yang dapat dilewati. Secara default, compiler Compose menandai fungsi composable sebagai dapat dilewati jika semua argumennya memiliki nilai yang stabil. Mode skipping kuat mengubah hal ini.

Dengan mengaktifkan strong skipping, semua fungsi composable yang dapat dimulai ulang akan menjadi dapat dilewati. Hal ini berlaku terlepas dari apakah parameter tersebut tidak stabil atau tidak. Fungsi composable yang tidak dapat dimulai ulang tetap tidak dapat dilewati.

Kapan harus melewati

Untuk menentukan apakah akan melewati composable selama rekomposisi, Compose membandingkan nilai setiap parameter dengan nilai sebelumnya. Jenis perbandingan bergantung pada stabilitas parameter.

  • Parameter yang tidak stabil dibandingkan menggunakan persamaan instance (===)
  • Parameter stabil dibandingkan menggunakan persamaan objek (Object.equals())

Jika semua parameter memenuhi persyaratan ini, Compose akan melewati composable selama rekomposisi.

Anda mungkin ingin composable memilih tidak ikut mode lewati kuat. Artinya, Anda mungkin menginginkan composable yang dapat dimulai ulang, tetapi tidak dapat dilewati. Dalam hal ini, gunakan anotasi @NonSkippableComposable.

@NonSkippableComposable
@Composable
fun MyNonSkippableComposable {}

Menganotasi class sebagai stabil

Jika Anda ingin objek dibandingkan menggunakan kesetaraan objek (Object.equals()), bukan kesetaraan instance (===), terus anotasikan class yang diberikan dengan @Stable atau @Immutable.

Ingatlah konsekuensi berikut sebelum menambahkan @Stable atau @Immutable:

  • Class dengan properti stabil dalam modul Compose sudah stabil: Class dengan properti val dari jenis stabil dalam modul yang dikompilasi dengan compiler Compose otomatis disimpulkan sebagai stabil dan menggunakan .equals() tanpa memerlukan @Immutable atau @Stable.
  • Hanya anotasi class dengan pemeriksaan .equals() yang murah: Tambahkan @Stable atau @Immutable saat compiler tidak dapat menyimpulkan stabilitas (seperti class dari modul non-Compose) dan instance baru dengan nilai yang identik sering dialokasikan, asalkan pemeriksaan .equals() class tidak mahal.
  • Berhati-hatilah saat menganotasi model dengan koleksi: Menambahkan @Stable atau @Immutable ke model yang berisi koleksi (atau mengganti List dengan ImmutableList) akan menyebabkan Compose membandingkan setiap elemen dalam koleksi dengan .equals() pada setiap penerusan rekomposisi. Untuk koleksi atau model besar yang digunakan dalam tata letak lambat (LazyColumn, LazyRow, LazyGrid), membandingkan setiap elemen dapat lebih lambat daripada menggunakan kesetaraan instance (===) atau merekomposisi secara langsung.

Memoisasi lambda

Mode skipping kuat juga memungkinkan lebih banyak memoization lambda di dalam composable. Jika mode skipping kuat diaktifkan, setiap lambda di dalam fungsi composable akan otomatis diingat.

Contoh

Untuk mencapai memoisasi lambda di dalam composable saat menggunakan pengabaian kuat, compiler menggabungkan lambda Anda dengan panggilan remember. Kunci ini diberi kunci dengan pengambilan lambda.

Pertimbangkan kasus saat Anda memiliki lambda seperti dalam contoh berikut:

@Composable
fun MyComposable(unstableObject: Unstable, stableObject: Stable) {
    val lambda = {
        use(unstableObject)
        use(stableObject)
    }
}

Dengan mengaktifkan mode skipping kuat, compiler akan mememoisasi lambda dengan menggabungkannya dalam panggilan remember:

@Composable
fun MyComposable(unstableObject: Unstable, stableObject: Stable) {
    val lambda = remember(unstableObject, stableObject) {
        {
            use(unstableObject)
            use(stableObject)
        }
    }
}

Kunci mengikuti aturan perbandingan yang sama dengan fungsi composable. Runtime membandingkan kunci yang tidak stabil menggunakan kesetaraan instance. Fungsi ini membandingkan kunci stabil menggunakan kesetaraan objek.

Memoization dan rekomposisi

Pengoptimalan ini sangat meningkatkan jumlah composable yang dilewati runtime selama rekomposisi. Tanpa memoization, runtime akan jauh lebih mungkin mengalokasikan lambda baru ke composable apa pun yang menggunakan parameter lambda selama rekomposisi. Akibatnya, lambda baru memiliki parameter yang tidak sama dengan komposisi terakhir. Hal ini menyebabkan rekomposisi.

Menghindari memoization

Jika Anda memiliki lambda yang tidak ingin dimemokan, gunakan anotasi @DontMemoize.

val lambda = @DontMemoize {
    ...
}

Ukuran APK

Saat dikompilasi, Composable yang dapat dilewati menghasilkan lebih banyak kode yang dihasilkan daripada composable yang tidak dapat dilewati. Dengan mengaktifkan fitur strong skipping, compiler akan menandai hampir semua composable sebagai dapat dilewati dan menggabungkan semua lambda dalam remember{...}. Oleh karena itu, mengaktifkan mode skipping kuat memiliki dampak yang sangat kecil pada ukuran APK aplikasi Anda.

Mengaktifkan mode lewati kuat di Now In Android meningkatkan ukuran APK sebesar 4 kB. Perbedaan ukuran sangat bergantung pada jumlah composable yang sebelumnya tidak dapat dilewati yang ada di aplikasi tertentu, tetapi seharusnya relatif kecil.