0Pricing
Android Academy · Pelajaran

Caching dan Kinerja

Dasar-dasar caching di memori dan disk.

Caching dan Kinerja adalah pelajaran Android Academy gratis di CoddyKit. Ini adalah pelajaran 3 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar Android Academy, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus Android Academy mencakup 4 pelajaran total.

Mengapa Cache Penting

Mengunduh dan mendekode gambar membutuhkan banyak sumber daya: menggunakan bandwidth, baterai, dan CPU. Jika Anda mengambil ulang gambar yang sama setiap kali daftar digulir, aplikasi akan terasa lambat dan menghabiskan data.

Cache menyimpan gambar yang telah didekode dan byte yang telah diunduh, sehingga permintaan berikutnya hampir instan. Secara default, Coil menyediakan dua cache: cache dalam memori (cepat, bitmap yang telah didekode) dan cache disk (persisten, byte mentah).

Pelajaran ini menjelaskan cara kerja keduanya dan cara menyesuaikannya.

Dua Lapisan: Memori dan Disk

Coil memeriksa cache secara berurutan:

  • Cache memori: menyimpan bitmap yang baru-baru ini digunakan dan telah didekode di RAM. Jika ditemukan di sini, hasilnya instan dan tidak perlu didekode.
  • Cache disk: menyimpan byte asli yang diunduh di perangkat. Jika ditemukan di sini, jaringan tidak diperlukan, tetapi gambar tetap harus didekode.
  • Jaringan: jalur yang lambat, hanya digunakan jika kedua cache tidak menemukan hasil.

Memori cepat, tetapi kecil dan dihapus saat aplikasi berhenti; disk lebih besar dan tetap tersedia setelah aplikasi dimulai ulang.

Mengonfigurasi ImageLoader

Cache berada di ImageLoader, mesin di balik setiap permintaan. Biasanya Anda membuat satu pemuat khusus dan menggunakannya kembali. Di sini kita mengatur ukuran cache memori sebagai persentase RAM yang tersedia dan cache disk dengan batas byte tetap.

Pemuat tunggal mencegah cache ganda dan pemborosan memori.

import android.content.Context
import coil3.ImageLoader
import coil3.disk.DiskCache
import coil3.memory.MemoryCache
import okio.Path.Companion.toOkioPath

fun newImageLoader(context: Context): ImageLoader =
    ImageLoader.Builder(context)
        .memoryCache {
            MemoryCache.Builder()
                .maxSizePercent(context, 0.25) // 25% of app RAM
                .build()
        }
        .diskCache {
            DiskCache.Builder()
                .directory(context.cacheDir.resolve("image_cache").toOkioPath())
                .maxSizeBytes(50L * 1024 * 1024) // 50 MB
                .build()
        }
        .build()

Menyediakan Pemuat Tunggal

Coil 3 memungkinkan Anda menetapkan satu pemuat untuk seluruh aplikasi dengan menerapkan SingletonImageLoader.Factory pada kelas Application. Setelah itu, setiap AsyncImage menggunakannya secara otomatis, sehingga Anda tidak perlu meneruskan pemuat setiap kali.

import android.app.Application
import coil3.ImageLoader
import coil3.PlatformContext
import coil3.SingletonImageLoader

class MyApp : Application(), SingletonImageLoader.Factory {
    override fun newImageLoader(context: PlatformContext): ImageLoader =
        ImageLoader.Builder(context)
            .crossfade(true)
            .build()
}

Mengontrol Kebijakan Cache

Setiap permintaan dapat memilih untuk menggunakan atau tidak menggunakan cache dengan memoryCachePolicy dan diskCachePolicy. Kebijakannya adalah ENABLED, READ_ONLY, WRITE_ONLY, atau DISABLED.

Misalnya, nonaktifkan cache memori untuk gambar besar yang hanya digunakan sekali dan tidak ingin disimpan di RAM, atau nonaktifkan disk untuk konten sensitif.

import android.content.Context
import coil3.request.CachePolicy
import coil3.request.ImageRequest

fun noMemoryCacheRequest(context: Context, url: String) =
    ImageRequest.Builder(context)
        .data(url)
        .memoryCachePolicy(CachePolicy.DISABLED)
        .diskCachePolicy(CachePolicy.ENABLED)
        .build()

Ubah Ukuran: Jangan Dekode Bitmap Berukuran Besar

Kesalahan performa terbesar adalah mendekode foto berukuran 4000x3000 menjadi gambar mini berukuran 100dp. Hal itu membuang memori dan waktu. Secara default, Coil menyesuaikan ukuran bitmap dengan batas terukur composable, sehingga AsyncImage kecil mendekode bitmap kecil.

Anda dapat memaksa ukuran target secara eksplisit dengan size() pada permintaan jika dimensinya sudah diketahui.

import android.content.Context
import coil3.request.ImageRequest
import coil3.size.Size

fun thumbnailRequest(context: Context, url: String) =
    ImageRequest.Builder(context)
        .data(url)
        .size(Size(200, 200)) // decode at most 200x200
        .build()

Kunci Cache yang Stabil

Coil menghasilkan kunci cache dari data permintaan. Jika URL Anda memiliki parameter kueri yang berubah-ubah (seperti token bertanda tangan), gambar yang sama akan mendapatkan kunci berbeda dan tidak pernah ditemukan di cache.

Tetapkan memoryCacheKey dan diskCacheKey secara eksplisit berdasarkan bagian yang stabil (misalnya ID gambar) agar caching berfungsi.

import android.content.Context
import coil3.request.ImageRequest

fun stableKeyRequest(context: Context, id: String, signedUrl: String) =
    ImageRequest.Builder(context)
        .data(signedUrl)
        .memoryCacheKey("image_$id")
        .diskCacheKey("image_$id")
        .build()

Memuat Gambar Terlebih Dahulu

Untuk pengalaman yang lebih lancar, Anda dapat menghangatkan cache sebelum gambar ditampilkan, misalnya mengambil terlebih dahulu halaman berikutnya dari umpan. Gunakan enqueue milik pemuat dengan permintaan yang tidak memiliki target.

Saat pengguna mencapai gambar tersebut, gambar sudah tersimpan di cache dan langsung muncul.

import android.content.Context
import coil3.ImageLoader
import coil3.request.ImageRequest

fun preload(context: Context, loader: ImageLoader, urls: List<String>) {
    urls.forEach { url ->
        val request = ImageRequest.Builder(context)
            .data(url)
            .build()
        loader.enqueue(request)
    }
}

Menghapus Cache

Terkadang Anda perlu mengosongkan ruang atau memaksa penyegaran, misalnya setelah pengguna memperbarui avatarnya. Anda dapat menghapus cache memori, cache disk, atau menghapus satu kunci.

Menghapus semuanya membutuhkan banyak sumber daya, jadi jika memungkinkan, lebih baik hapus kunci tertentu.

import coil3.ImageLoader
import coil3.memory.MemoryCache

fun refreshAvatar(loader: ImageLoader, key: String) {
    // Remove one entry so the next load refetches
    loader.memoryCache?.remove(MemoryCache.Key(key))
    loader.diskCache?.remove(key)
}

fun clearAll(loader: ImageLoader) {
    loader.memoryCache?.clear()
    // Disk clearing is heavier; do it sparingly
}

Crossfade vs Hasil Cache

Crossfade terlihat bagus untuk pemuatan melalui jaringan, tetapi dapat terasa lambat ketika gambar langsung berasal dari cache memori dan seharusnya bisa muncul secara instan. Coil menangani hal ini dengan cerdas: secara default, Coil melewati animasi crossfade untuk hasil dari cache memori dan hanya menganimasikan gambar yang benar-benar dimuat.

Dengan begitu, Anda mendapatkan transisi halus saat pemuatan pertama dan tampilan instan saat menggulir gambar yang sudah tersimpan di cache, tanpa pekerjaan tambahan.

import android.content.Context
import coil3.request.ImageRequest
import coil3.request.crossfade

fun feedRequest(context: Context, url: String) =
    ImageRequest.Builder(context)
        .data(url)
        // Crossfade plays on real loads; memory-cache hits show instantly
        .crossfade(true)
        .build()

Daftar Periksa Performa untuk Daftar

Saat menampilkan banyak gambar dalam LazyColumn atau kisi, ikuti aturan berikut agar pengguliran tetap lancar:

  • Berikan ukuran tetap untuk setiap gambar agar Coil mendekode bitmap kecil.
  • Gunakan kembali satu ImageLoader tunggal agar cache digunakan bersama.
  • Gunakan ContentScale.Crop untuk menghindari perubahan tata letak.
  • Pertahankan kunci cache agar tetap stabil saat pemuatan ulang.
  • Biarkan Coil membatalkan permintaan di luar layar secara otomatis, jangan menghambatnya.
import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
import androidx.compose.foundation.lazy.grid.items
import androidx.compose.foundation.layout.aspectRatio
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.ContentScale
import coil3.compose.AsyncImage

@Composable
fun PhotoGrid(urls: List<String>) {
    LazyVerticalGrid(columns = GridCells.Fixed(3)) {
        items(urls) { url ->
            AsyncImage(
                model = url,
                contentDescription = null,
                contentScale = ContentScale.Crop,
                modifier = Modifier.aspectRatio(1f)
            )
        }
    }
}

Pemeriksaan Singkat

Coil memeriksa cache sebelum mengakses jaringan. Cache mana yang paling cepat saat ditemukan karena sepenuhnya melewati proses dekode?

Rangkuman

Anda telah mempelajari cara Coil menjaga gambar tetap cepat:

  • Dua cache: memori (telah didekode, cepat, kecil) dan disk (byte mentah, persisten, lebih besar).
  • Konfigurasikan ukurannya pada ImageLoader khusus, lalu sediakan satu pemuat melalui SingletonImageLoader.Factory.
  • Sesuaikan perilaku setiap permintaan dengan memoryCachePolicy dan diskCachePolicy.
  • Selalu dekode sesuai ukuran tampilan; tetapkan size() secara eksplisit jika diperlukan.
  • Gunakan kunci cache yang stabil, muat terlebih dahulu gambar yang akan datang, dan hapus kunci tertentu untuk menyegarkan cache.

Berikutnya: melampaui gambar untuk memutar audio dan video.

Pertanyaan yang Sering Diajukan

Apakah pelajaran “Caching dan Kinerja” gratis?

Ya — teks lengkap “Caching dan Kinerja” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus Android Academy, upgrade ke CoddyKit PRO. Kursus Android Academy mencakup 4 pelajaran total.

Apa yang akan aku pelajari di “Caching dan Kinerja”?

Dasar-dasar caching di memori dan disk. Kamu berlatih Android Academy dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.

Apakah aku perlu pengalaman untuk memulai Android Academy?

Tidak diperlukan pengalaman sebelumnya. Android Academy di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 3 dari 4.

Berapa lama pelajaran “Caching dan Kinerja” memakan waktu?

Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.

Bisakah aku menulis dan menjalankan kode dalam pelajaran Android Academy ini?

Ya. Setiap pelajaran Android Academy menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.

Semua pelajaran dalam kursus ini

  1. Memuat Gambar dengan Coil
  2. Placeholder dan Status Error
  3. Caching dan Kinerja
  4. Memutar Audio dan Video
← Kembali ke Android Academy