Cold Start — суштина, хладно покретање и оптимизација у Android-у

Аутор: IT Sectr Објављено: 2026-03-31 Време читања: 9 мин

Cold Start — ово је пун циклус покретања Android апликације, који почиње из нултог стања, када процес апликације не постоји у меморији, а Activity није креирана. Систем креира нови процес, учитава класе, иницијализује Application, креира Activity и извршава прво исцртавање. Према подацима Google, 2024, хладно покретање на уређајима средњег сегмента може трајати од 1 до 5 секунди, а сваких 100 мс кашњења смањује вероватноћу задржавања корисника за 3%.

Главно

  • Cold Start — покретање Android апликације од нуле: нови процес, учитавање класа, иницијализација
  • Метрика се мери од старта процеса до првог исцртавања (TTID или TTFD)
  • Фазе старта: креирање процеса → Application.onCreate → Activity.onCreate → први кадар
  • Оптимизација укључује лењо иницијализовање, Baseline Profiles и смањење величине DEX-а
  • Google Play користи Cold Start као један од кључних показатеља у Android Vitals-у

Шта је Cold Start

Cold Start (хладно покретање) — ово је сценарио у коме се Android апликација покреће из најпочетнијег стања: оперативни систем креира нови процес (fork из Zygote-а), издваја меморију, учитава DEX код у ART, иницијализује класе и креира инстанцу Application, а затим прву Activity. Пре старта апликације у меморији уређаја нема никаквих података о њој, осим кешираних слика класа, ако се користи Background Dexopt.

Када се дешава Cold Start

Хладно покретање се дешава у три случаја: при првом покретању након инсталације апликације, при покретању након рестарта уређаја, и при покретању након што је систем истоварио процес због недостатка меморије. На уређајима са 2–4 ГБ РАМ-а систем прилично агресивно истоварује позадинске процесе, па се Cold Start може дешавати при сваком повратку у апликацију након неколико сати мировања. У Android 12+ систем може сачувати замрзнут процес (freeze / cached), али при активној уштеди меморије (OOM-killer) процес ће бити уништен.

Зашто је Cold Start критична метрика

Према подацима Google-а (Find My Device report, 2023), 65% корисника затвара апликацију ако се није отворила за 3 секунде. За друштвене мреже и месинџере, где се корисник враћа десетине пута дневно, Cold Start директно утиче на retention. У Google Play Console метрика Cold Start улази у одељак Android Vitals и приказује се као један од показатеља ANR-а и перформанси. Апликација која прелази праг „лошег" Cold Start-а (више од 5 секунди на 25% уређаја) добија упозорење у конзоли и може бити ниже рангирана у претрази.

Cold Start vs Warm Start vs Hot Start

Android разликује три типа покретања апликације, од којих сваки има различито трајање, утицај на UX и приступе оптимизацији. Разумевање разлике је неопходно за избор исправне стратегије профилисања.

Тип покретањаСтање процесаApplication.onCreateТипично време
ColdНема процесаИзвршава се1–5 секунди
WarmПроцес постоји, Activity немаНе извршава се200–600 мс
HotПроцес + Activity у меморијиНе извршава се< 200 мс

Warm Start се дешава када процес апликације већ постоји у позадини, али је Activity уништена (на пример, корисник се вратио након дуге паузе, и систем је ослободио меморију Activity-а). Hot Start — када корисник смањи апликацију и одмах је поново отвори: Activity је паузирана и обнављање захтева минимално време. За корисника Cold Start је најприметнији тип покретања, и управо његова оптимизација даје највећи напредак у UX.

Прелаз између типова

Cold Start може постати Warm Start након што је апликација покренута бар једном — ART кешира компиловане слике класа (Image in Boot Profile) и поновно учитавање DEX-а је брже. Зато је друго покретање након првог Cold Start-а обично 20–40% брже. Ако апликација користи Baseline Profiles, профили се учитавају при првом покретању и други старт може бити још бржи: Google Play, који је објавио Baseline Profiles, убрзао је Cold Start за 30% на уређајима са Android 12+.

Фазе хладног покретања

Cold Start се састоји од строго дефинисаних фаза, од којих свака може бити измерена и оптимизована независно. Познавање фаза помаже да се одреди у којој етапи апликација губи време. Google издваја четири главне фазе: креирање процеса, иницијализација Application-а, креирање Activity-а и први кадар.

Фаза 1: Креирање процеса (fork)

Android систем (ActivityManagerService) креира нови процес путем fork-а из процеса Zygote. Zygote је претходно учитан процес са common класама Android-а. Fork се извршава за 30–80 мс — то је време које апликација не може да контролише. Након fork-а покреће се ActivityThread — инстанца главне петље апликације. У овој етапи такође се дешава учитавање класа преко ClassLoader-а, и ART почиње да интерпретира први бајт-код. Ако апликација користи много статичких иницијализатора, ова фаза се може одужити.

Фаза 2: Application.onCreate

Одмах након старта ActivityThread-а позива се Application.onCreate. Овде програмери најчешће праве грешку, иницијализујући све одједном: Crashlytics, Firebase, мрежне клијенте, базе података, Dagger компоненте, DI контејнере. Свака таква иницијализација је време блокирано на главном току. Ако се Application.onCreate извршава 500 мс, свих тих пола секунди корисник види бели (или црни) екран. Оптимално трајање ове фазе — мање од 200 мс на средњем уређају.

Фаза 3: Activity.onCreate

Након иницијализације Application-а креира се инстанца Activity (MainActivity или Launcher Activity). Позива се Activity.onCreate, где се дешава setContentView, иницијализација фрагмената, подешавање ViewModel-а, претплата на LiveData/Flow. Ако onCreate синхроно на главном току извршава учитавање података (SharedPreferences, SQLite, API), фаза се продужава. Циљ — уложити onCreate у 200–400 мс на средњем уређају.

Фаза 4: Први кадар (TTFD)

Након завршетка onCreate-а почиње прво исцртавање: мера, layout, draw. Тај тренутак се назива TTFD (Time To First Draw). Ако апликација користи splash екран (преко SplashScreen API-ја на Android 12+ или преко теме), исцртавање се може десити брже, али ће корисник ипак чекати док се splash сакрије. Идеални TTFD за Cold Start — мање од 1.5 секунде.

Како измерити Cold Start

Мерење Cold Start-а захтева специјалне алате, јер обично логирање (Log.d) почиње са радом тек након креирања Application-а, а тајминг fork-а и учитавања класа остаје ван домашаја. Google препоручује три метода: ADB команде, Android Vitals и кастомне perf макрое.

Мерење преко ADB-а

Најједноставнији и поновљив начин — команда adb shell am start -S -W. Флаг -S присилно зауставља апликацију пре покретања (гарантује Cold Start). Команда излази три метрике: ThisTime (време старта Activity-а), TotalTime (укупно време укључујући покретање процеса) и WaitTime (време укључујући сва кашњења Activity Manager-а). За чистоћу мерења направите 5–7 мерења и узмите медијану — појединачна мерења су подложна шуму (CPU throttling, позадинско оптерећење).

bash
# Присилни Cold Start са мерењем
$ adb shell am start -S -W \
    com.example.app/.MainActivity

# Излаз команде:
# ThisTime: 1842 ms
# TotalTime: 1842 ms
# WaitTime: 1855 ms

Android Vitals (Google Play Console)

Google Play Console прикупља анонимне метрике са свих уређаја на којима је инсталирана апликација. У одељку Android Vitals → Launch time приказује се медијанска расподела Cold Start-а по моделу уређаја и верзији Android-а. Ово је једини начин да се виде реални показатељи на уређајима корисника, а не на тестним девајсима. Ако на Redmi 9A (2 ГБ РАМ-а) Cold Start прелази 5 секунди, а на Pixel 8 — 1.2 секунде, проблем је у количини меморије и броју класа. Google такође приказује кориснички опажајно кашњење (user-perceptible delay) на основу 25-ог перцентила.

Macrobenchmark

Google Jetpack Macrobenchmark (библиотека androidx.benchmark) омогућава писање инструментираних тестова покретања апликације. Тест инсталира апликацију, покреће је из хладног стања и мери време до првог кадра. Macrobenchmark аутоматски ради 20 прогона, одбацује изузетке и приказује стабилне перцентиле. За CI/CD се могу упоредити baseline и тренутно покретање — ако се време повећало, CI пајплајн може да падне.

Како оптимизовати Cold Start

Оптимизација Cold Start-а је систематски рад, који обухвата неколико нивоа апликације: код, ресурсе, конфигурацију изградње и архитектуру иницијализације. Google препоручује да се почне од најскупљег — Application.onCreate — и иде ка ситницама.

Лења иницијализација (Lazy Init)

Пребаците сву иницијализацију, која није потребна на старту, из Application.onCreate у прву тачку коришћења. Firebase, Crashlytics, analytics SDK, push-нотификације, DI компоненте — све се може иницијализовати након исцртавања првог екрана. Користите Lazy (by lazy) у Kotlin-у или ContentProvider иницијализацију са експлицитним позивом initialize(context). Према подацима Google-а (Android Performance, 2023), лења иницијализација смањује Cold Start за 40–60% за апликације које користе 5+ SDK-а.

Baseline Profiles

Baseline Profiles — ово је AOT компилација критичних класа и метода, који се користе на старту апликације. Без Baseline Profiles ART интерпретира DEX код или га компилује JIT-ом, што захтева време. Са профилима ART компилује наведене методе у нативни код (AOT) при инсталацији апликације. Google тврди да Baseline Profiles дају убрзање Cold Start-а за 15–40% на Android 9+ и до 60% са ART оптимизацијама Android 12+. За креирање профила користите плагин androidx.benchmark:benchmark-baseline-profile-gradle-plugin.

App Startup Library

Библиотека androidx.startup омогућава уређивање иницијализације компоненти и њено извршавање у једном ContentProvider-у. Уместо неколико ContentProvider-а од различитих библиотека (сваки додаје 1–2 мс хладном старту), App Startup их обједињује у граф зависности и иницијализује строго по потреби. На старту се извршавају само компоненте са @Initializer, означене као потребне за први екран. За остале се поставља флаг needEarlyInit = false — покрећу се након првог исцртавања.

kotlin
// App Startup Initializer — иницијализација након старта
class AnalyticsInitializer : Initializer<Unit> {
    override fun create(context: Context) {
        Analytics.init(context)
    }
    override fun dependencies() = listOf<Class<out Initializer<*>>>()
}

// У AndroidManifest.xml означавамо као необавезно
// <meta-data android:name="AnalyticsInitializer"
//     android:value="false" />

Смањење величине DEX-а

Величина DEX фајла директно утиче на време његовог учитавања у ART. Користите R8/ProGuard за обфускацију и уклањање мртвог кода (MinifyEnabled = true). Укључите android:extractNativeLibs="false" у манифесту, да APK не распакује .so фајлове при инсталацији. За пројекте са 10 Reference Tracking класа додајте startup-priority само за први екран. Сваки сувишни метод у DEX-у додаје 0.5–2 мс учитавању, а за апликације са 50k+ метода (multidex са primary dex) — до 300 мс.

Cold Start у Android Vitals-у

Android Vitals у Google Play Console (Launch time section) прикупља податке са свих уређаја на којима је инсталирана апликација, уз сагласност корисника на анонимну дијагностику. Метрике се деле у три категорије: „good" (добар), „moderate" (средњи), „bad" (лош), у зависности од времена Cold Start-а.

Праг вредности Google-а

Google дефинише „bad" Cold Start као време које прелази 5 секунди на било ком уређају. Међутим, у пракси за флагманске уређаје (Snapdragon 8 Gen) добрим се сматра време мање од 1.5 секунди, за средњи сегмент — мање од 2.5 секунди, за буџетни — мање од 4 секунди. Android Vitals приказује медијану по сваком device model, што омогућава да се разуме на којим уређајима се апликација споро покреће. Ако је Cold Start лош на Samsung A-series или Xiaomi Redmi уређајима, разлог је најчешће слаба flash меморија и мали обим РАМ-а (убрзање кроз Baseline Profiles даје највећи ефекат управо на таквим уређајима).

Како Google Play користи метрику

Поред приказа у конзоли, метрика Cold Start утиче на оцену квалитета апликације у Google Play Search-у. Апликације са високим процентом „bad" покретања добијају ознаку „Performance warning" на страници инсталације, што смањује конверзију. Према подацима Google-а (Android Performance Playbook, 2024), апликације које су отклониле Cold Start проблеме у просеку повећавају конверзију инсталације за 5% и побољшавају показатељ retention (D1) за 3–7%.

Интеграција са Firebase Performance

За детаљније праћење користите Firebase Performance Monitoring. Он прати Cold Start на нивоу сесија, разврстава по верзијама апликације и верзијама Android-а. За разлику од Android Vitals-а, Firebase приказује trace дијаграм утрошеног времена по фазама. На пример, може се видети да је на верзији 3.2.0 Application.onCreate постао 800 мс (због нове библиотеке push-нотификација), а на верзији 3.2.1 — 200 мс (након исправке).

Примери кода за оптимизацију

У наставку су дата два практична примера, која директно убрзавају Cold Start: преношење иницијализације SDK-а након старта и коришћење SplashScreen API-ја.

Преношење иницијализације са Application.onCreate

Типична грешка — иницијализација свих SDK-а у Application.onCreate. У наставку је показано како пренети некритичну иницијализацију у корутину, која се покреће након исцртавања првог кадра. Важно: Firebase, Crashlytics и Crash Reporting SDK морају бити иницијализовани на старту — не смеју се одлагати, јер хватају крашове при иницијализацији других компоненти. За остале користите lifecycleScope при првој Activity.

kotlin
// ❌ Лоше — сва иницијализација у Application.onCreate
class App : Application() {
    override fun onCreate() {
        super.onCreate()
        Firebase.init(this) // критично
        Analytics.init(this) // може касније
        Database.init(this) // може касније
        ImageLoader.init(this) // може касније
    }
}

// ✅ Добро — Firebase на старту, остало after inflate
class App : Application() {
    override fun onCreate() {
        super.onCreate()
        Firebase.init(this)
    }
}

// У MainActivity након првог кадра:
lifecycleScope.launchWhenResumed {
    initializeNonCriticalSdks()
}

SplashScreen API

На Android 12+ користите званични SplashScreen API, који приказује system сплеш (икона апликације на тамној/светлој позадини) одмах при старту процеса. То скрива време иницијализације од корисника — он види сплеш, а не бели екран. За старије уређаје користите theme-based splash (Theme.SplashScreen у стиловима). Важно: сплеш не сме трајати дуже од 300 мс — ако за то време апликација није спремна, нацртајте „стални" скелетон (shimmer) и приказујте напредак учитавања.

kotlin
// 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)
// У themes.xml:
// <style name="Theme.App.Starting" parent="Theme.SplashScreen">
//   <item name="windowSplashScreenBackground">@color/white</item>
//   <item name="windowSplashScreenAnimatedIcon">@mipmap/ic_launcher</item>
// </style>

Често постављана питања

Зашто је Cold Start на емулатору бржи него на уређају?

Емулатор користи моћан хост рачунар и емулира процесор са хардверским убрзањем (HAXM / WHPX). Физички уређаји, посебно буџетни (eMMC меморија уместо UFS), имају много спорије I/O. Препоручује се мерење Cold Start-а на физичком уређају средњег сегмента, да би се добили реалистични подаци.

Који Cold Start се сматра прихватљивим?

По препорукама Google-а, медијански Cold Start треба да буде мање од 2 секунди на уређајима средњег сегмента. За флагмане — мање од 1.5 секунди. За буџетне уређаје (2 ГБ РАМ-а) допустиво је до 4 секунди, али се препоручује оптимизација до 3 секунде. Вредности веће од 5 секунди сматрају се критичним.

Да ли величина иконе утиче на брзину Cold Start-а?

Индиректно — да. Ако је у манифесту наведена vector икона (AdaptiveIcon), она мора бити компилована у drawable при старту. Ако икона садржи сложене путање (pathData са десетинама кривих), компилација траје 10–30 мс. Користите VectorDrawable са оптимизованим pathData (преко SVGOMG-а или Android Studio Vector Asset-а).

Да ли је потребно оптимизовати Cold Start у Feature Module-у?

Да, ако се Feature Module (Android App Bundle) учитава на захтев (on-demand), његов Cold Start се рачуна од тренутка клика на фичу до првог кадра. On-demand модули се учитавају преко Play Core Library, а њихова инсталација додаје 500–3000 мс времену старта. Оптимизујте код фиче исто као и главни модул.

Како Multidex утиче на Cold Start?

Апликације са више од 64k метода захтевају Multidex. То значи да ART мора да учита неколико DEX фајлова, што повећава време Cold Start-а за 200–800 мс у зависности од броја classes.dex. Користите minSdk 21+ (ART са подршком за native multidex) и подесите primary dex преко --main-dex-list, да критичне класе буду у првом DEX фајлу.

Закључци

  • Cold Start — потпуно покретање апликације са креирањем новог процеса, временом 1–5 секунди
  • Мери се преко ADB shell am start -S -W или Macrobenchmark-а у CI/CD-у
  • Четири фазе: fork → Application.onCreate → Activity.onCreate → први кадар
  • Оптимизација: лења иницијализација, Baseline Profiles, App Startup Library, R8 компресија
  • Google Play оцењује Cold Start као „bad" при времену већем од 5 секунди на било ком уређају
  • SplashScreen API на Android 12+ скрива време иницијализације иза system сплеша
  • Сваких 100 мс кашњења смањује retention корисника за 3%

Развићемо мобилну апликацију под кључ

IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.

Разговарајте о пројекту

Прочитајте такође