Cold Start je úplný cyklus spuštění aplikace Android z nulového stavu, kdy proces aplikace neexistuje v paměti a Activity nebyla vytvořena. Systém vytvoří nový proces, načte třídy, inicializuje Application, vytvoří Activity a provede první vykreslení. Podle Google, 2024 může studený start na zařízeních střední třídy trvat 1 až 5 sekund a každých 100 ms zpoždění snižuje pravděpodobnost udržení uživatele o 3 %.
Hlavní body
Cold Start (studený start) je scénář, při kterém se aplikace Android spouští z nejzákladnějšího stavu: operační systém vytvoří nový proces (fork z Zygote), alokuje paměť, načte DEX kód do ART, inicializuje třídy a vytvoří instanci Application a poté první Activity. Před spuštěním aplikace o ní v paměti zařízení nejsou žádná data, kromě cacheovaných obrazů tříd, pokud se používá Background Dexopt.
Studený start nastává ve třech případech: při prvním spuštění po instalaci aplikace, při spuštění po restartu zařízení a při spuštění poté, co systém odstranil proces kvůli nedostatku paměti. Na zařízeních s 2–4 GB RAM systém agresivně odstraňuje procesy na pozadí, takže Cold Start může nastat při každém návratu do aplikace po několika hodinách nečinnosti. V Android 12+ může systém uchovat zmrazený proces (freeze / cached), ale při aktivním šetření paměti (OOM-killer) bude proces zničen.
Podle Google (Find My Device report, 2023) 65 % uživatelů zavře aplikaci, pokud se neotevře do 3 sekund. U sociálních sítí a messengerů, kam se uživatel vrací desítkykrát denně, Cold Start přímo ovlivňuje retenci. V konzoli Google Play je metrika Cold Start součástí sekce Android Vitals a zobrazuje se jako jeden z ukazatelů ANR a výkonu. Aplikace překračující práh „špatného" Cold Start (více než 5 sekund na 25 % zařízení) obdrží varování v konzoli a může být v hledání snížena.
Android rozlišuje tři typy spuštění aplikace, každý s jinou dobou trvání, dopadem na UX a přístupy k optimalizaci. Pochopení rozdílu je nezbytné pro výběr správné strategie profilování.
| Typ spuštění | Stav procesu | Application.onCreate | Typická doba |
|---|---|---|---|
| Cold | Žádný proces | Provádí se | 1–5 sekund |
| Warm | Proces existuje, Activity ne | Neprovádí se | 200–600 ms |
| Hot | Proces + Activity v paměti | Neprovádí se | < 200 ms |
Warm Start nastává, když proces aplikace již existuje na pozadí, ale Activity byla zničena (např. uživatel se vrátil po dlouhé pauze a systém uvolnil paměť Activity). Hot Start — když uživatel aplikaci minimalizuje a ihned ji znovu otevře: Activity je pozastavena a obnovení trvá minimální dobu. Pro uživatele je Cold Start nejvíce znatelným typem spuštění a jeho optimalizace přináší největší zlepšení UX.
Cold Start se může stát Warm Start poté, co byla aplikace spuštěna alespoň jednou — ART ukládá do mezipaměti zkompilované obrazy tříd (Image in Boot Profile) a opětovné načtení DEX je rychlejší. Druhé spuštění po prvním Cold Start je proto obvykle o 20–40 % rychlejší. Pokud aplikace používá Baseline Profiles, profily se načtou při prvním spuštění a druhý start může být ještě rychlejší: Google Play, který Baseline Profiles zveřejnil, zrychlil Cold Start o 30 % na zařízeních s Android 12+.
Cold Start se skládá z přesně definovaných fází, z nichž každou lze měřit a optimalizovat nezávisle. Znalost fází pomáhá určit, v jaké fázi aplikace ztrácí čas. Google rozlišuje čtyři hlavní fáze: vytvoření procesu, inicializace Application, vytvoření Activity a první snímek.
Systém Android (ActivityManagerService) vytvoří nový proces pomocí fork z procesu Zygote. Zygote je předem načtený proces s běžnými třídami Android. Fork se provádí za 30–80 ms — to je čas, který aplikace nemůže ovlivnit. Po forku se spustí ActivityThread — instance hlavní smyčky aplikace. V této fázi také dochází k načtení tříd přes ClassLoader a ART začíná interpretovat první bajtkód. Pokud aplikace používá mnoho statických inicializátorů, tato fáze se může protáhnout.
Ihned po spuštění ActivityThread je voláno Application.onCreate. Zde vývojář nejčastěji chybuje tím, že inicializuje vše najednou: Crashlytics, Firebase, síťové klienty, databáze, Dagger komponenty, DI kontejnery. Každá taková inicializace je čas blokovaný na hlavním vlákně. Pokud Application.onCreate trvá 500 ms, uživatel po tuto půlsekundu vidí bílou (nebo černou) obrazovku. Optimální délka této fáze je méně než 200 ms na průměrném zařízení.
Po inicializaci Application je vytvořena instance Activity (MainActivity nebo Launcher Activity). Je voláno Activity.onCreate, kde dochází k setContentView, inicializaci fragmentů, nastavení ViewModel, přihlášení k LiveData/Flow. Pokud onCreate načítá data (SharedPreferences, SQLite, API) synchronně na hlavním vlákně, fáze se prodlužuje. Cílem je udržet onCreate v rozmezí 200–400 ms na průměrném zařízení.
Po dokončení onCreate začíná první vykreslení: measure, layout, draw. Tento okamžik se nazývá TTFD (Time To First Draw). Pokud aplikace používá úvodní obrazovku (přes SplashScreen API na Android 12+ nebo přes téma), vykreslení může proběhnout rychleji, ale uživatel bude stále čekat, dokud splash nezmizí. Ideální TTFD pro Cold Start je méně než 1,5 sekundy.
Měření Cold Start vyžaduje speciální nástroje, protože běžné logování (Log.d) začíná fungovat až po vytvoření Application a načasování forku a načítání tříd zůstává mimo dosah. Google doporučuje tři metody: ADB příkazy, Android Vitals a vlastní perf makra.
Nejjednodušší a reprodukovatelný způsob je příkaz adb shell am start -S -W. Přepínač -S vynuceně zastaví aplikaci před spuštěním (zaručuje Cold Start). Příkaz vypíše tři metriky: ThisTime (čas spuštění Activity), TotalTime (celkový čas včetně spuštění procesu) a WaitTime (čas včetně všech zpoždění Activity Manageru). Pro čisté měření proveďte 5–7 měření a vezměte medián — jednotlivá měření podléhají šumu (CPU throttling, zátěž na pozadí).
# Vynucený Cold Start s měřením
$ adb shell am start -S -W \
com.example.app/.MainActivity
# Výstup příkazu:
# ThisTime: 1842 ms
# TotalTime: 1842 ms
# WaitTime: 1855 ms
Google Play Console shromažďuje anonymní metriky ze všech zařízení, kde je aplikace nainstalována. V sekci Android Vitals → Launch time se zobrazuje mediánové rozdělení Cold Start podle modelu zařízení a verze Android. To je jediný způsob, jak vidět skutečné ukazatele na zařízeních uživatelů, ne na testovacích zařízeních. Pokud na Redmi 9A (2 GB RAM) Cold Start přesahuje 5 sekund a na Pixel 8 — 1,2 sekundy, problém je v kapacitě paměti a počtu tříd. Google také zobrazuje vnímané zpoždění uživatelem (user-perceptible delay) na základě 25. percentilu.
Google Jetpack Macrobenchmark (knihovna androidx.benchmark) umožňuje psát instrumentované testy spuštění aplikace. Test nainstaluje aplikaci, spustí ji ve studeném stavu a změří čas do prvního snímku. Macrobenchmark automaticky provede 20 běhů, odstraní odlehlé hodnoty a zobrazí stabilní percentily. Pro CI/CD lze porovnat baseline a aktuální spuštění — pokud se čas zvýšil, CI pipeline může selhat.
Optimalizace Cold Start je systémová práce zasahující několik úrovní aplikace: kód, zdroje, konfiguraci sestavení a architekturu inicializace. Google doporučuje začít od nejdražšího — Application.onCreate — a postupovat k menším věcem.
Přesuňte veškerou inicializaci, která není při startu vyžadována, z Application.onCreate do prvního místa použití. Firebase, Crashlytics, analytics SDK, push notifikace, DI komponenty — vše lze inicializovat po vykreslení první obrazovky. Použijte Lazy (by lazy) v Kotlin nebo inicializaci ContentProvider s explicitním voláním initialize(context). Podle Google (Android Performance, 2023) lená inicializace zkracuje Cold Start o 40–60 % u aplikací používajících 5+ SDK.
Baseline Profiles jsou AOT kompilace kritických tříd a metod, které se používají při spuštění aplikace. Bez Baseline Profiles ART interpretuje DEX kód nebo jej kompiluje pomocí JIT, což zabírá čas. S profily ART kompiluje zadané metody do nativního kódu (AOT) při instalaci aplikace. Google tvrdí, že Baseline Profiles zrychlují Cold Start o 15–40 % na Android 9+ a až o 60 % s optimalizacemi ART Android 12+. Pro vytváření profilů použijte plugin androidx.benchmark:benchmark-baseline-profile-gradle-plugin.
Knihovna androidx.startup umožňuje uspořádat inicializaci komponent a provádět ji v jednom ContentProvider. Namísto několika ContentProviderů od různých knihoven (každý přidává 1–2 ms ke studenému startu) je App Startup spojuje do grafu závislostí a inicializuje pouze v případě potřeby. Při startu se provádějí pouze komponenty označené @Initializer a potřebné pro první obrazovku. Pro ostatní je nastaven příznak needEarlyInit = false — spouštějí se po prvním vykreslení.
// App Startup Initializer — inicializace po startu
class AnalyticsInitializer : Initializer<Unit> {
override fun create(context: Context) {
Analytics.init(context)
}
override fun dependencies() = listOf<Class<out Initializer<*>>>()
}
// V AndroidManifest.xml označíme jako volitelné
// <meta-data android:name="AnalyticsInitializer"
// android:value="false" />
Velikost DEX souboru přímo ovlivňuje dobu jeho načítání ART. Použijte R8/ProGuard pro obfuskaci a odstranění mrtvého kódu (MinifyEnabled = true). Zapněte android:extractNativeLibs="false" v manifestu, aby APK při instalaci nerozbaloval .so soubory. U projektů s více než 10 třídami Reference Tracking přidávejte startup-priority pouze pro první obrazovku. Každá nadbytečná metoda v DEX přidává 0,5–2 ms k načítání a u aplikací s 50k+ metodami (multidex s primary dex) — až 300 ms.
Android Vitals v Google Play Console (sekce Launch time) shromažďuje data ze všech zařízení, kde je aplikace nainstalována, za předpokladu, že uživatel souhlasil s anonymní diagnostikou. Metriky jsou rozděleny do tří kategorií: „good" (dobrý), „moderate" (střední), „bad" (špatný), v závislosti na čase Cold Start.
Google definuje „bad" Cold Start jako čas přesahující 5 sekund na jakémkoli zařízení. V praxi se u vlajkových zařízení (Snapdragon 8 Gen) považuje za dobrý čas méně než 1,5 sekundy, u střední třídy — méně než 2,5 sekundy, u levných — méně než 4 sekundy. Android Vitals zobrazuje medián pro každý device model, což umožňuje pochopit, na kterých zařízeních aplikace startuje pomalu. Pokud je Cold Start špatný na zařízeních Samsung A-series nebo Xiaomi Redmi, příčinou je obvykle slabá flash paměť a malá RAM (zrychlení pomocí Baseline Profiles dává největší efekt právě na takových zařízeních).
Kromě zobrazení v konzoli metrika Cold Start ovlivňuje hodnocení kvality aplikace ve vyhledávání Google Play. Aplikace s vysokým procentem „špatných" startů získávají na stránce instalace štítek „Performance warning", což snižuje konverzi. Podle Google (Android Performance Playbook, 2024) aplikace, které vyřešily problémy s Cold Start, zvyšují průměrně konverzi instalace o 5 % a zlepšují retenci (D1) o 3–7 %.
Pro podrobnější monitorování použijte Firebase Performance Monitoring. Sleduje Cold Start na úrovni relací, rozděluje podle verzí aplikace a verzí Android. Na rozdíl od Android Vitals Firebase zobrazuje trace diagram stráveného času podle fází. Lze například vidět, že ve verzi 3.2.0 Application.onCreate trvalo 800 ms (kvůli nové knihovně push notifikací) a ve verzi 3.2.1 — 200 ms (po opravě).
Níže jsou uvedeny dva praktické příklady, které přímo zrychlují Cold Start: přesun inicializace SDK po startu a použití SplashScreen API.
Typickou chybou je inicializace všech SDK v Application.onCreate. Níže je ukázáno, jak přesunout nekritickou inicializaci do corutiny, která se spouští po vykreslení prvního snímku. Důležité: Firebase, Crashlytics a Crash Reporting SDK musí být inicializovány při startu — nelze je odložit, protože zachycují pády při inicializaci ostatních komponent. Pro ostatní použijte lifecycleScope při první Activity.
// ❌ Špatně — veškerá inicializace v Application.onCreate
class App : Application() {
override fun onCreate() {
super.onCreate()
Firebase.init(this) // kritické
Analytics.init(this) // lze později
Database.init(this) // lze později
ImageLoader.init(this) // lze později
}
}
// ✅ Dobře — Firebase při startu, zbytek after inflate
class App : Application() {
override fun onCreate() {
super.onCreate()
Firebase.init(this)
}
}
// V MainActivity po prvním snímku:
lifecycleScope.launchWhenResumed {
initializeNonCriticalSdks()
}
Na Android 12+ použijte oficiální SplashScreen API, které zobrazí system-splash (ikonu aplikace na tmavém/světlém pozadí) ihned při spuštění procesu. To skryje dobu inicializace před uživatelem — vidí splash, nikoli bílou obrazovku. Pro starší zařízení použijte theme-based splash (Theme.SplashScreen ve stylech). Důležité: splash by neměl trvat déle než 300 ms — pokud aplikace není do té doby připravena, nakreslete „trvalou" kostru (shimmer) a zobrazte průběh načítání.
// 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)
// V themes.xml:
// <style name="Theme.App.Starting" parent="Theme.SplashScreen">
// <item name="windowSplashScreenBackground">@color/white</item>
// <item name="windowSplashScreenAnimatedIcon">@mipmap/ic_launcher</item>
// </style>
Často kladené otázky
Emulátor používá výkonný hostitelský počítač a emuluje procesor s hardwarovou akcelerací (HAXM / WHPX). Fyzická zařízení, zejména levná (paměť eMMC místo UFS), mají mnohem pomalejší I/O. Doporučuje se měřit Cold Start na fyzickém zařízení střední třídy pro získání realistických dat.
Podle doporučení Google by mediánový Cold Start měl být méně než 2 sekundy na zařízeních střední třídy. Pro vlajková zařízení — méně než 1,5 sekundy. Pro levná zařízení (2 GB RAM) je přijatelných až 5 sekund, ale doporučuje se optimalizovat na 3 sekundy. Hodnoty nad 5 sekund jsou považovány za kritické.
Nepřímo — ano. Pokud je v manifestu uvedena vektorová ikona (AdaptiveIcon), musí být při startu zkompilována do drawable. Pokud ikona obsahuje složité cesty (pathData s desítkami křivek), kompilace trvá 10–30 ms. Použijte VectorDrawable s optimalizovaným pathData (přes SVGOMG nebo Android Studio Vector Asset).
Ano, pokud se Feature Module (Android App Bundle) načítá na vyžádání (on-demand), jeho Cold Start se počítá od okamžiku kliknutí na funkci po první snímek. On-demand moduly se načítají přes Play Core Library a jejich instalace přidává 500–3000 ms k době startu. Optimalizujte kód funkce stejně jako hlavní modul.
Aplikace s více než 64k metodami vyžadují Multidex. To znamená, že ART musí načíst několik DEX souborů, což zvyšuje čas Cold Start o 200–800 ms v závislosti na počtu classes.dex. Použijte minSdk 21+ (ART s nativním multidexem) a nakonfigurujte primary dex přes --main-dex-list, aby kritické třídy byly v prvním DEX souboru.
Shrnutí
Vyvineme mobilní aplikaci na klíč
IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.
Přečtěte si také