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 начинается первая отрисовка: мера, лэйаут, draw. Этот момент называется TTFD (Time To First Draw). Если приложение использует splash-экран (через SplashScreen API на Android 12+ или через theme), отрисовка может произойти быстрее, но пользователь всё равно будет ждать, пока 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-notifications, 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 года. Мы проконсультируем вас и предложим наилучшее решение.

Обсудить проект

Читайте также