Cold Start är den fullständiga startcykeln för en Android-app från nolltillstånd, när appens process inte finns i minnet och Activity inte har skapats. Systemet skapar en ny process, laddar klasser, initierar Application, skapar Activity och utför den första renderingen. Enligt Google, 2024 kan en kallstart på medelklassenheter ta 1 till 5 sekunder, och varje 100 ms fördröjning minskar sannolikheten för att behålla användaren med 3%.
Huvudpunkter
Cold Start (kallstart) är ett scenario där Android-appen startas från det mest ursprungliga tillståndet: operativsystemet skapar en ny process (fork från Zygote), allokerar minne, laddar DEX-kod till ART, initierar klasser och skapar en instans av Application, och sedan den första Activity. Innan appen startar finns inga data om den i enhetens minne, förutom cachade bilder av klasser om Background Dexopt används.
Kallstart inträffar i tre fall: vid första starten efter installation av appen, vid start efter omstart av enheten, och vid start efter att systemet tagit bort processen på grund av minnesbrist. På enheter med 2–4 GB RAM tar systemet aggressivt bort bakgrundsprocesser, så Cold Start kan inträffa vid varje återgång till appen efter flera timmars inaktivitet. I Android 12+ kan systemet behålla en frusen process (freeze / cached), men vid aktiv minnessparande (OOM-killer) kommer processen att förstöras.
Enligt Google (Find My Device report, 2023) stänger 65% av användarna appen om den inte öppnas inom 3 sekunder. För sociala nätverk och meddelandetjänster, där användaren återvänder dussintals gånger om dagen, påverkar Cold Start direkt retentionen. I Google Play Console ingår Cold Start-metriken i sektionen Android Vitals och visas som en av ANR- och prestandaindikatorerna. En app som överskrider tröskeln för "dålig" Cold Start (mer än 5 sekunder på 25% av enheterna) får en varning i konsolen och kan nedgraderas i sökningen.
Android skiljer på tre typer av appstarter, var och en med olika varaktighet, påverkan på UX och optimeringsmetoder. Att förstå skillnaden är nödvändigt för att välja rätt profileringsstrategi.
| Starttyp | Processtatus | Application.onCreate | Typisk tid |
|---|---|---|---|
| Cold | Ingen process | Utförs | 1–5 sekunder |
| Warm | Process finns, Activity saknas | Utförs inte | 200–600 ms |
| Hot | Process + Activity i minnet | Utförs inte | < 200 ms |
Warm Start inträffar när appens process redan finns i bakgrunden, men Activity har förstörts (t.ex. användaren återvände efter en lång paus och systemet frigjorde Activity-minnet). Hot Start — när användaren minimerar appen och omedelbart öppnar den igen: Activity är pausad och återställningen tar minimal tid. För användaren är Cold Start den mest märkbara starttypen, och dess optimering ger den största förbättringen i UX.
Cold Start kan bli Warm Start efter att appen har startats minst en gång — ART cachar kompilerade klassbilder (Image in Boot Profile) och omladdning av DEX går snabbare. Därför är den andra starten efter den första Cold Start vanligtvis 20–40% snabbare. Om appen använder Baseline Profiles, laddas profilerna vid första starten och den andra starten kan vara ännu snabbare: Google Play, som publicerade Baseline Profiles, snabbade upp Cold Start med 30% på enheter med Android 12+.
Cold Start består av strikt definierade faser, som var och en kan mätas och optimeras oberoende. Kunskap om faserna hjälper till att avgöra i vilket skede appen förlorar tid. Google särskiljer fyra huvudfaser: processkapning, Application-initiering, Activity-skapande och första bildrutan.
Android-systemet (ActivityManagerService) skapar en ny process genom fork från Zygote-processen. Zygote är en förladdad process med gemensamma Android-klasser. Fork utförs på 30–80 ms — detta är tid som appen inte kan kontrollera. Efter fork startar ActivityThread — instansen av appens huvudloop. I detta skede sker också klassladdning via ClassLoader, och ART börjar tolka den första bytekoden. Om appen använder många statiska initierare kan denna fas förlängas.
Omedelbart efter att ActivityThread startar anropas Application.onCreate. Här gör utvecklaren oftast misstaget att initiera allt på en gång: Crashlytics, Firebase, nätverksklienter, databaser, Dagger-komponenter, DI-behållare. Varje sådan initiering är tid som blockeras på huvudtråden. Om Application.onCreate tar 500 ms ser användaren under den halva sekunden en vit (eller svart) skärm. Optimal varaktighet för denna fas är mindre än 200 ms på en medelenhet.
Efter initiering av Application skapas en instans av Activity (MainActivity eller Launcher Activity). Activity.onCreate anropas, där setContentView, initiering av fragment, ViewModel-konfiguration, prenumeration på LiveData/Flow sker. Om onCreate laddar data (SharedPreferences, SQLite, API) synkront på huvudtråden förlängs fasen. Målet är att hålla onCreate inom 200–400 ms på en medelenhet.
Efter att onCreate är klar börjar den första renderingen: measure, layout, draw. Detta ögonblick kallas TTFD (Time To First Draw). Om appen använder en splash-skärm (via SplashScreen API på Android 12+ eller via tema) kan renderingen ske snabbare, men användaren väntar fortfarande tills splash försvinner. Idealisk TTFD för Cold Start är mindre än 1,5 sekunder.
Mätning av Cold Start kräver speciella verktyg, eftersom vanlig loggning (Log.d) börjar fungera först efter att Application skapats, och tiden för fork och klassladdning förblir otillgänglig. Google rekommenderar tre metoder: ADB-kommandon, Android Vitals och anpassade perf-makron.
Det enklaste och reproducerbara sättet är kommandot adb shell am start -S -W. Flaggan -S stoppar tvångsmässigt appen före start (garanterar Cold Start). Kommandot ger tre mätvärden: ThisTime (starttid för Activity), TotalTime (total tid inklusive processstart) och WaitTime (tid inklusive alla fördröjningar från Activity Manager). För ren mätning, gör 5–7 mätningar och ta medianen — enskilda mätningar är känsliga för brus (CPU throttling, bakgrundsbelastning).
# Tvingad Cold Start med mätning
$ adb shell am start -S -W \
com.example.app/.MainActivity
# Kommandoutdata:
# ThisTime: 1842 ms
# TotalTime: 1842 ms
# WaitTime: 1855 ms
Google Play Console samlar in anonyma mätvärden från alla enheter där appen är installerad. I sektionen Android Vitals → Launch time visas medianfördelningen av Cold Start per enhetsmodell och Android-version. Detta är det enda sättet att se verkliga indikatorer på användarnas enheter, inte på testenheter. Om Cold Start på Redmi 9A (2 GB RAM) överstiger 5 sekunder och på Pixel 8 är 1,2 sekunder, ligger problemet i minneskapaciteten och antalet klasser. Google visar också användarens upplevda fördröjning (user-perceptible delay) baserat på 25:e percentilen.
Google Jetpack Macrobenchmark (biblioteket androidx.benchmark) gör det möjligt att skriva instrumenterade tester för appstart. Testet installerar appen, startar den i kallt tillstånd och mäter tiden till första bildrutan. Macrobenchmark gör automatiskt 20 körningar, kastar bort avvikelser och visar stabila percentiler. För CI/CD kan baseline jämföras med nuvarande start — om tiden har ökat kan CI-pipelinen misslyckas.
Optimering av Cold Start är ett systematiskt arbete som påverkar flera nivåer av appen: kod, resurser, byggkonfiguration och initieringsarkitektur. Google rekommenderar att börja med det dyraste — Application.onCreate — och gå vidare till mindre saker.
Flytta all initiering som inte krävs vid start från Application.onCreate till den första användningspunkten. Firebase, Crashlytics, analytics SDK, push-notiser, DI-komponenter — allt kan initieras efter rendering av första skärmen. Använd Lazy (by lazy) i Kotlin eller ContentProvider-initiering med explicit anrop av initialize(context). Enligt Google (Android Performance, 2023) minskar lat initiering Cold Start med 40–60% för appar som använder 5+ SDK.
Baseline Profiles är AOT-kompilering av kritiska klasser och metoder som används vid appstart. Utan Baseline Profiles tolkar ART DEX-kod eller kompilerar den med JIT, vilket tar tid. Med profiler kompilerar ART de angivna metoderna till nativ kod (AOT) vid installation av appen. Google hävdar att Baseline Profiles snabbar upp Cold Start med 15–40% på Android 9+ och upp till 60% med ART-optimeringar i Android 12+. För att skapa profiler, använd plugin androidx.benchmark:benchmark-baseline-profile-gradle-plugin.
Biblioteket androidx.startup gör det möjligt att organisera komponentinitiering och utföra den i en enda ContentProvider. Istället för flera ContentProviders från olika bibliotek (varje lägger till 1–2 ms till kallstart) kombinerar App Startup dem i ett beroendediagram och initierar endast vid behov. Vid start utförs endast komponenter märkta med @Initializer som behövs för den första skärmen. För övriga sätts flaggan needEarlyInit = false — de startar efter första renderingen.
// App Startup Initializer — initiering efter start
class AnalyticsInitializer : Initializer<Unit> {
override fun create(context: Context) {
Analytics.init(context)
}
override fun dependencies() = listOf<Class<out Initializer<*>>>()
}
// I AndroidManifest.xml markeras som valfritt
// <meta-data android:name="AnalyticsInitializer"
// android:value="false" />
Storleken på DEX-filen påverkar direkt laddningstiden av ART. Använd R8/ProGuard för obfuskering och borttagning av död kod (MinifyEnabled = true). Aktivera android:extractNativeLibs="false" i manifestet så att APK inte packar upp .so-filer vid installation. För projekt med fler än 10 Reference Tracking-klasser, lägg till startup-priority endast för första skärmen. Varje överflödig metod i DEX lägger till 0,5–2 ms till laddning, och för appar med 50k+ metoder (multidex med primary dex) — upp till 300 ms.
Android Vitals i Google Play Console (sektionen Launch time) samlar in data från alla enheter där appen är installerad, under förutsättning att användaren samtyckt till anonym diagnostik. Mätvärden delas in i tre kategorier: "good" (bra), "moderate" (medel), "bad" (dålig), beroende på Cold Start-tiden.
Google definierar "bad" Cold Start som tid över 5 sekunder på vilken enhet som helst. I praktiken anses för flaggskeppsenheter (Snapdragon 8 Gen) bra tid vara mindre än 1,5 sekunder, för medelklass — mindre än 2,5 sekunder, för budget — mindre än 4 sekunder. Android Vitals visar median per device model, vilket hjälper att förstå på vilka enheter appen startar långsamt. Om Cold Start är dåligt på Samsung A-series eller Xiaomi Redmi-enheter, är orsaken oftast svagt flash-minne och lite RAM (acceleration via Baseline Profiles ger störst effekt just på sådana enheter).
Förutom att visas i konsolen påverkar Cold Start-metriken kvalitetsbedömningen av appen i Google Play Search. Appar med hög andel "dåliga" starter får en etikett "Performance warning" på installationssidan, vilket minskar konverteringen. Enligt Google (Android Performance Playbook, 2024) ökar appar som åtgärdar Cold Start-problem installationskonverteringen med i genomsnitt 5% och förbättrar retention (D1) med 3–7%.
För mer detaljerad övervakning, använd Firebase Performance Monitoring. Den spårar Cold Start på sessionsnivå, delar upp efter appversion och Android-version. Till skillnad från Android Vitals visar Firebase ett spårdiagram över förbrukad tid per fas. Till exempel kan man se att i version 3.2.0 tog Application.onCreate 800 ms (på grund av ett nytt push-meddelandebibliotek), och i version 3.2.1 — 200 ms (efter korrigering).
Nedan finns två praktiska exempel som direkt snabbar upp Cold Start: flytta SDK-initiering efter start och använda SplashScreen API.
Ett typiskt misstag är att initiera alla SDK i Application.onCreate. Nedan visas hur man flyttar icke-kritisk initiering till en korutin som startar efter rendering av första bildrutan. Viktigt: Firebase, Crashlytics och Crash Reporting SDK måste initieras vid start — de kan inte försenas eftersom de fångar krascher vid initiering av andra komponenter. För övriga, använd lifecycleScope vid första Activity.
// ❌ Dåligt — all initiering i Application.onCreate
class App : Application() {
override fun onCreate() {
super.onCreate()
Firebase.init(this) // kritiskt
Analytics.init(this) // kan göras senare
Database.init(this) // kan göras senare
ImageLoader.init(this) // kan göras senare
}
}
// ✅ Bra — Firebase vid start, resten after inflate
class App : Application() {
override fun onCreate() {
super.onCreate()
Firebase.init(this)
}
}
// I MainActivity efter första bildrutan:
lifecycleScope.launchWhenResumed {
initializeNonCriticalSdks()
}
På Android 12+, använd officiella SplashScreen API, som visar en system-splash (appikon på mörk/ljus bakgrund) omedelbart vid processstart. Detta döljer initieringstiden för användaren — han ser en splash istället för en vit skärm. För äldre enheter, använd theme-based splash (Theme.SplashScreen i stilar). Viktigt: splash bör inte vara längre än 300 ms — om appen inte är redo inom den tiden, rita ett "permanent" skelett (shimmer) och visa laddningsförloppet.
// SplashScreen API — Android 12+
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
val splashScreen = installSplashScreen()
splashScreen.setKeepOnScreenCondition {
isReady.value == false
}
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
}
// Theme-based splash (Android 5-11)
// I themes.xml:
// <style name="Theme.App.Starting" parent="Theme.SplashScreen">
// <item name="windowSplashScreenBackground">@color/white</item>
// <item name="windowSplashScreenAnimatedIcon">@mipmap/ic_launcher</item>
// </style>
Vanliga frågor
Emulatorn använder en kraftfull värddator och emulerar processorn med hårdvaruacceleration (HAXM / WHPX). Fysiska enheter, särskilt budgetmodeller (eMMC-minne istället för UFS), har mycket långsammare I/O. Det rekommenderas att mäta Cold Start på en fysisk medelklassenhet för att få realistiska data.
Enligt Googles rekommendationer bör median Cold Start vara mindre än 2 sekunder på medelklassenheter. För flaggskepp — mindre än 1,5 sekunder. För budgetenheter (2 GB RAM) är upp till 4 sekunder acceptabelt, men optimering till 3 sekunder rekommenderas. Värden över 5 sekunder anses kritiska.
Indirekt — ja. Om en vektorikon (AdaptiveIcon) anges i manifestet måste den kompileras till drawable vid start. Om ikonen innehåller komplexa sökvägar (pathData med dussintals kurvor) tar kompileringen 10–30 ms. Använd VectorDrawable med optimerad pathData (via SVGOMG eller Android Studio Vector Asset).
Ja, om Feature Module (Android App Bundle) laddas on-demand, beräknas dess Cold Start från klicket på funktionen till första bildrutan. On-demand-moduler laddas via Play Core Library och deras installation lägger till 500–3000 ms till starttiden. Optimera funktionskoden precis som huvudmodulen.
Appar med fler än 64k metoder kräver Multidex. Det innebär att ART måste ladda flera DEX-filer, vilket ökar Cold Start-tiden med 200–800 ms beroende på antalet classes.dex. Använd minSdk 21+ (ART med inbyggt multidex) och konfigurera primary dex via --main-dex-list så att kritiska klasser finns i den första DEX-filen.
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å