Hurtigbufring og ytelse
Grunnleggende om hurtigbufring i minne og på disk.
Hurtigbufring og ytelse er en gratis leksjon i Android Academy på CoddyKit. Dette er leksjon 3 av 4. Du kan lese valgfritt 3 leksjoner fra denne læringsstien gratis i sin helhet – deretter låser CoddyKit PRO opp alle leksjoner, samt praktisk øving med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Den er en del av læringsløpet i Android Academy, og fremdriften din synkroniseres mellom nettet og CoddyKit-appen. Kurset i Android Academy inneholder totalt 4 leksjoner.
Hvorfor hurtigbufring er viktig
Nedlasting og dekoding av et bilde er ressurskrevende: Det bruker båndbredde, batteri og CPU. Hvis du laster ned det samme bildet på nytt hver gang en liste rulles, oppleves appen som treg, og den bruker unødvendig mye data.
Hurtigbufring lagrer dekodede bilder og nedlastede byte, slik at neste forespørsel nesten blir umiddelbar. Coil leveres som standard med to hurtigbuffere: et hurtigbuffer i minnet (raskt, dekodede bitmaps) og et hurtigbuffer på disken (varig, rå byte).
Denne leksjonen forklarer hvordan de fungerer, og hvordan du kan finjustere dem.
To lag: minne og disk
Coil sjekker hurtigbufferne i denne rekkefølgen:
- Hurtigbuffer i minnet: inneholder nylig brukte, dekodede bitmaps i RAM. Et treff her er umiddelbart, og dekoding er ikke nødvendig.
- Hurtigbuffer på disken: lagrer de opprinnelig nedlastede bytene på enheten. Et treff her gjør at nettverket kan hoppes over, men bildet må fortsatt dekodes.
- Nettverk: den langsomme banen, som bare brukes når begge hurtigbufferne ikke har treff.
Minne er raskt, men begrenset, og tømmes når appen avsluttes. Diskplassen er større og beholdes når appen startes på nytt.
Konfigurere ImageLoader
Hurtigbufferne ligger på ImageLoader, motoren bak alle forespørsler. Vanligvis bygger du én egendefinert loader og bruker den på nytt. Her setter vi størrelsen på hurtigbufferet i minnet til en prosentandel av tilgjengelig RAM og hurtigbufferet på disken til en fast mengde byte.
En singleton-loader unngår dupliserte hurtigbuffere og unødvendig minnebruk.
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()Tilordne en singleton-loader
Coil 3 lar deg angi én loader for hele applikasjonen ved å implementere SingletonImageLoader.Factory i Application-klassen. Deretter bruker alle AsyncImage-forekomster den automatisk, slik at du slipper å sende med en loader hver gang.
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()
}Styring av hurtigbufferregler
Hver forespørsel kan slå hurtigbufring av eller på med memoryCachePolicy og diskCachePolicy. Reglene er ENABLED, READ_ONLY, WRITE_ONLY eller DISABLED.
Du kan for eksempel deaktivere hurtigbufferet i minnet for svært store engangsbilder som du ikke vil beholde i RAM, eller deaktivere hurtigbufferet på disken for sensitivt innhold.
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()Endre størrelse: Ikke dekodér enorme bitmaps
Den klart største ytelsesfeilen er å dekode et bilde på 4000x3000 piksler til et miniatyrbilde på 100dp. Det sløser med både minne og tid. Som standard tilpasser Coil bitmapen til de målte grensene til composable-en, slik at en liten AsyncImage dekoder en liten bitmap.
Du kan tvinge frem en bestemt målstørrelse med size() i forespørselen når du kjenner dimensjonene.
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()Stabile hurtigbuffernøkler
Coil utleder en hurtigbuffernøkkel fra dataene i forespørselen. Hvis URL-ene dine inneholder parametere som endres (for eksempel et signert token), får identiske bilder forskjellige nøkler og treffer aldri hurtigbufferet.
Angi eksplisitte memoryCacheKey- og diskCacheKey-verdier basert på den stabile delen, for eksempel bilde-ID-en, slik at hurtigbufring fungerer.
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()Forhåndslaste bilder
For en jevnere opplevelse kan du varme opp hurtigbufferet før et bilde vises, for eksempel ved å forhåndslaste neste side i en feed. Bruk loaderens enqueue med en forespørsel som ikke har noe mål.
Når brukeren kommer til bildet, ligger det allerede i hurtigbufferet og vises umiddelbart.
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)
}
}Tømme hurtigbufferet
Av og til trenger du å frigjøre plass eller tvinge frem en oppdatering, for eksempel etter at brukeren har oppdatert profilbildet sitt. Du kan tømme hurtigbufferet i minnet, hurtigbufferet på disken eller fjerne én enkelt nøkkel.
Det er ressurskrevende å tømme alt, så foretrekk å fjerne bestemte nøkler når du kan.
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 kontra treff i hurtigbufferet
Crossfade ser flott ut ved lasting fra nettverket, men kan føles tregt når et bilde kommer direkte fra hurtigbufferet i minnet og kunne ha blitt vist umiddelbart. Coil håndterer dette intelligent: Som standard hopper det over crossfade-animasjonen ved treff i minnehurtigbufferet og animerer bare bilder som faktisk er lastet inn.
Dermed får du jevne overganger ved første lasting og umiddelbar visning når du ruller gjennom bufrede bilder, uten at du trenger å gjøre noe ekstra.
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()Ytelsessjekkliste for lister
Når du viser mange bilder i en LazyColumn eller et rutenett, bør du følge disse reglene for jevn rulling:
- Gi hvert bilde en fast størrelse, slik at Coil dekoder en liten bitmap.
- Bruk én singleton-
ImageLoaderpå nytt, slik at hurtigbufferne deles. - Bruk
ContentScale.Cropfor å unngå forskyvninger i oppsettet. - Hold hurtigbuffernøklene stabile mellom omlastinger.
- La Coil avbryte forespørsler utenfor skjermen automatisk – ikke motarbeid dette.
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)
)
}
}
}Hurtigsjekk
Coil sjekker hurtigbufferne før den bruker nettverket. Hvilket hurtigbuffer er raskest ved treff, fordi det hopper over dekodingen helt?
Oppsummering
Du har lært hvordan Coil holder bilder raske:
- To hurtigbuffere: minne (dekodet, raskt, lite) og disk (rå byte, varig, større).
- Konfigurer størrelsene på en egendefinert
ImageLoader, og gjør én tilgjengelig viaSingletonImageLoader.Factory. - Finjuster oppførselen per forespørsel med
memoryCachePolicyogdiskCachePolicy. - Dekodér alltid i visningsstørrelsen, og angi eksplisitt
size()ved behov. - Bruk stabile hurtigbuffernøkler, forhåndslast kommende bilder, og fjern bestemte nøkler for å oppdatere.
neste: ta steget videre fra bilder til avspilling av lyd og video.
Lær deg Kotlin med en AI-veileder – gratis
Skriv og kjør ekte kode i nettleseren, få umiddelbar hjelp fra en AI-veileder som er tilgjengelig døgnet rundt, og fortsett der du slapp – på nettet eller i appen.
- Kurs
- 36
- Leksjoner
- 152
Ofte stilte spørsmål
Er leksjonen «Hurtigbufring og ytelse» gratis?
Ja – du kan lese valgfritt 3 av leksjonene i læringsstien Android Academy, inkludert «Hurtigbufring og ytelse», gratis i sin helhet her på nettet. Deretter låser CoddyKit PRO opp alle leksjoner, samt interaktiv øving med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Kurset i Android Academy inneholder totalt 4 leksjoner.
Hva lærer jeg i «Hurtigbufring og ytelse»?
Grunnleggende om hurtigbufring i minne og på disk. Du øver på Android Academy med praktisk kode som du kjører direkte i nettleseren, mens en AI-veileder som er tilgjengelig døgnet rundt, svarer på spørsmålene dine mens du jobber deg gjennom leksjonen.
Trenger jeg erfaring for å begynne med Android Academy?
Ingen tidligere erfaring er nødvendig. Android Academy på CoddyKit er lagt opp for både nybegynnere og viderekomne, så De kan begynne her eller helt fra start og lære i Deres eget tempo. Dette er leksjon 3 av 4.
Hvor lang tid tar leksjonen «Hurtigbufring og ytelse»?
De fleste CoddyKit-leksjoner tar omtrent 5–10 minutter. Hver leksjon er kort og interaktiv, slik at De gjør jevne fremskritt og kan fortsette akkurat der De slapp – både på nettet og i appen.
Kan jeg skrive og kjøre kode i denne Android Academy-leksjonen?
Ja. Alle Android Academy-leksjoner har en innebygd kodeeditor, slik at De kan skrive og kjøre ekte kode direkte i nettleseren og få umiddelbar tilbakemelding fra AI – uten lokal konfigurering.
Alle leksjonene i dette kurset
- Laste inn bilder med Coil
- Plassholdere og feiltilstander
- Hurtigbufring og ytelse
- Spille av lyd og video