Cache-invalidering — processen att ta bort eller uppdatera inaktuell data i cachen för att säkerställa att informationen som appen får är aktuell. I mobil utveckling är invalidering kritisk: användaren förväntar sig färsk data utan full omladdning. Enligt Google Developers, 2025, minskar korrekt konfigurerad invalidering nätverksförfrågningar med 60% och förbättrar gränssnittets responsivitet.
Huvudpunkter
Cache-invalidering — processen att annullera eller uppdatera cachade poster som inte längre motsvarar det aktuella tillståndet för datakällan. Till skillnad från manuell rensning av hela cachen fungerar invalidering punktvis: endast de data vars aktualitet ifrågasätts.
Cachen lagrar kopior av data för snabb åtkomst. Med tiden kan originaldata i databasen eller på servern ändras — till exempel har användaren uppdaterat sin profil eller ett nytt inlägg har dykt upp i flödet. Om cachen inte invalideras visar appen inaktuell information, vilket i mobilappar leder till transaktionsfel, felaktig visning och förlorat förtroende.
Den största utmaningen med all invalidering — det välkända talesättet ”There are only two hard things in Computer Science: cache invalidation and naming things”. Komplexiteten ligger i att cachen inte vet när källan har ändrats, om den inte uttryckligen meddelas.
Enligt Martin Kleppmann, författare till boken ”Designing Data-Intensive Applications” (O’Reilly, 2017), kräver korrekt invalidering antingen centraliserad notifiering om ändringar eller en mekanism för att kontrollera aktualitet vid varje läsning — en kompromiss mellan prestanda och konsistens.
data class CacheEntryT(
val data: T,
val expiresAt: Long,
val version: Int = 0
)
fun CacheT.isValid(key: String): Boolean =
get(key)?.let { it.expiresAt > currentTimeMillis() && it.version == currentVersion(key) } ?: false
Denna kod visar ett enkelt tillvägagångssätt: en post i cachen anses giltig om TTL inte har löpt ut och versionen matchar den aktuella i källan. Versionshanteringsmekanismen — ett av de pålitliga sätten att undvika att visa inaktuell data.
Dataaktualitet — ett nyckelkrav för de flesta mobilappar: sociala nätverk, meddelandeappar, banktjänster, e-handelsplattformar. En användare som ser ett felaktigt saldo eller gamla meddelanden förlorar förtroendet för appen.
Förutom användarupplevelsen löser invalidering problemet med att spara trafik och batteri. Istället för periodisk full omladdning av data kan mobilappen invalidera endast ändrade poster och ladda dem punktvis. Enligt Meta Engineering (2024) minskade implementeringen av inkrementell invalidering i Facebook Lite trafikförbrukningen med 35% utan förlust av innehållsaktualitet.
En annan viktig aspekt — transaktionskonsistens. I appar med varukorg eller bokningar kan användning av inaktuell cache leda till dubbla debiteringar eller datakonflikter. Invalidering efter kritiska operationer garanterar att nästa förfrågan läser färsk data.
TTL — den enklaste strategin, där varje post i cachen får en fast livslängd. Efter att TTL har löpt ut anses data vara inaktuell och tas bort vid nästa läsning. TTL är idealiskt för data som uppdateras enligt schema — till exempel väder eller valutakurser. Nackdel: data kan vara inaktuell inom TTL-intervallet.
I Write-Through-strategin går varje dataändring genom cachen: skrivning utförs samtidigt till cachen och källan. Detta garanterar att cachen alltid innehåller den aktuella versionen. Nackdel — skrivfördröjningen ökar eftersom operationen inte slutförs förrän bekräftelse från källan. Write-Through är lämpligt för data som är kritisk för konsistens: kontosaldo, orderstatus.
Write-Behind — asynkron skrivning: data hamnar omedelbart i cachen och skrivs till källan senare av en separat process. Detta ger hög skrivprestanda men medför risk för dataförlust vid fel före synkronisering. I mobilappar används Write-Behind ofta för analys, loggar och icke-kritiska användaråtgärder.
Write-Invalidate — istället för att uppdatera cachen vid dataändring tar den helt enkelt bort (invaliderar) motsvarande post. Nästa läsning upptäcker en cache-miss och laddar färsk data från källan. Denna strategi är enkel att implementera och fungerar bra när läsförfrågningar är betydligt fler än skrivförfrågningar.
| Strategi | Läsprestanda | Skrivprestanda | Konsistens |
|---|---|---|---|
| TTL | Hög | Hög | Svag (möjligen inaktuell) |
| Write-Through | Hög | Medel | Stark |
| Write-Behind | Hög | Hög | Svag (möjligen förlust) |
| Write-Invalidate | Medel | Hög | Stark (vid nästa läsning) |
Valet av strategi beror på vad som är prioriterat för det specifika scenariot: svarstid, konsistens eller resursbesparing. Hybridmetoder — till exempel TTL med Write-Invalidate vid mottagning av ett push-meddelande — ger en optimal balans.
HTTP-cache — den första nivån på klientsidan. Webbläsaren eller mobilappen lagrar serversvar med Cache-Control och ETag-huvuden. Invalidering sker vid mottagning av ett 304 Not Modified-svar eller efter att max-age har löpt ut. ETag tillåter klienten att kontrollera en resurs aktualitet utan att ladda hela svaret.
Applikationscache — den andra nivån, hanterad av kod: cachar i minnet (LRU, LruCache i Android) eller disk (SQLite, Room, Realm). Invalidering här kontrolleras av utvecklaren. Enligt Android Developers (2025) minskar korrekt användning av Room med Flow och invalidering via triggers antalet UI-omritningar med 40%.
Servercache — den tredje nivån: Redis, Memcached, CDN. På denna nivå utförs invalidering via TTL, kommandon DEL/PURGE eller meddelandeförmedlare (RabbitMQ, Kafka). CDN-invalidering — en separat uppgift: på grund av CDN:ets distribuerade natur kan ett rensningskommando ta minuter att spridas. Enligt Cloudflare (2024) tar invalidering via Purge by URL i genomsnitt 5–15 sekunder för global spridning.
För samordning av invalidering på alla nivåer används en centraliserad cachtjänst eller händelseförmedlare. När data ändras publicerar källan en händelse och varje nivå får ett kommando att invalidera specifika nycklar. Detta förhindrar situationen där en nivå redan har uppdaterat data medan en annan fortsätter att leverera den inaktuella versionen.
För lång TTL — det vanligaste misstaget. Utvecklare ställer in TTL ”med reserv”, vilket leder till att användare ser inaktuell data i timmar eller dagar. Lösning: börja med kort TTL (1–5 minuter) och öka den först efter mätning av verkligt behov.
Invalidering av hela cachen vid en enda ändring — ett typiskt problem i mikrotjänstarkitektur. En användare uppdaterade sin avatar och cachen invalideras för alla. Vid ett stort antal användare orsakar detta Cache Stampede-effekten — en lavin av förfrågningar till källan. Lösning: invalidera endast den specifika användarens nyckel, inte hela cachen.
Avsaknad av invalidering vid skrivfel — om skrivning till källan misslyckas och cachen redan har uppdaterats hamnar appen i ett inkonsekvent tillstånd. Lösning: tvåfasinvalidering — rensa först cachen, skriv sedan till källan och återställ invalideringen vid fel.
Ignorering av distribuerad natur — i en klustermiljö betyder invalidering på en nod inte att andra noder har tagit emot kommandot. Utan en händelseförmedlare kommer en del av servrarna att fortsätta leverera inaktuell data. Redis Pub/Sub eller Apache Kafka löser detta problem genom att sprida invalideringshändelser.
Bestäm krav på aktualitet — hur kritiskt är det att data är färsk ”just nu”. För en nyhetsfeed är en fördröjning på 1–2 minuter acceptabel (TTL). För kontosaldo är fördröjning oacceptabel (Write-Through).
Bedöm ändringsfrekvensen — data som uppdateras en gång per dag (produktkatalog, stadsguide) fungerar utmärkt med TTL. Data som ändras tiotals gånger per sekund (online-status, valutakurser) kräver push-invalidering via WebSocket eller Firebase Cloud Messaging.
Ta hänsyn till kostnaden för att läsa källan — om källan är en dyr SQL-fråga över 10 tabeller eller ett externt API med begränsningar är det bättre att använda aggressiv cachning med lång TTL, men kompensera inaktuell data med push-invalidering. Om läsning är billig (in-memory lookup) kan kort TTL och Write-Invalidate användas.
Enligt Google I/O (2025) är det typiska mönstret för en mobilapp — Stale-While-Revalidate: användaren ser omedelbart cachad data och appen kontrollerar i bakgrunden dess aktualitet och uppdaterar den. Detta kombinerar svarstid och aktualitet utan kompromisser. HTTP-huvudet Cache-Control med direktivet stale-while-revalidate stöds från Android 10 och iOS 13.
Vanliga frågor
Invalidering — markering av en specifik post som inaktuell, varefter den uppdateras vid nästa läsning. Rensning av cache är fullständig borttagning av alla poster, vilket är dyrare och kan tillfälligt minska appens prestanda.
ETag — är en hash eller version av en resurs som servern returnerar i en HTTP-huvud. Vid en upprepad förfrågan skickar klienten If-None-Match med nuvarande ETag. Om resursen inte har ändrats svarar servern med 304 Not Modified och cachen förblir giltig.
Write-Through med versionshantering — mest pålitlig eftersom data alltid är konsistent. Men den ger störst skrivfördröjning. I praktiken används oftare TTL med push-invalidering för balans mellan prestanda och aktualitet.
Använd Probabilistic Early Expiration — varje förfrågan kontrollerar slumpmässigt cachens aktualitet före TTL:s utgång. Algoritmen XFetch (Vattani, 2015) beräknar sannolikheten för omräkning enligt formeln: p = (ttl - age) / (ttl * beta).
Använd nätverksfelsökningsverktyg: Charles Proxy, Proxyman eller den inbyggda Network Inspector i Android Studio och Xcode. Kontrollera att efter dataändring laddar nästa förfrågan verkligen den nya versionen och inte returnerar den cachade.
Sammanfattning
Vi utvecklar en mobil applikation nyckelfärdigt
IT Sectr skapar iOS- och Android-applikationer för startups och företag sedan 2017. Vi ger dig råd och föreslår den bästa lösningen.
Läs också