0Pricing
Android Academy · Урок

Профили запуска и Baseline Profiles

Ускоряйте холодный запуск

«Профили запуска и Baseline Profiles» — бесплатный урок Android Academy на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Android Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Android Academy содержит 4 уроков всего.

Первое впечатление: запуск приложения

Время запуска — первое, с чем сталкивается каждый пользователь. Google Play даже отмечает медленный запуск как проблему качества. Быстрый запуск с нуля создаёт ощущение качественного приложения, а медленный заставляет пользователей уходить.

В этом уроке Вы узнаете о трёх типах запуска, причинах медленного запуска и современных инструментах — библиотеке запуска приложения и базовых профилях, — которые значительно ускоряют запуск с нуля.

Запуск с нуля, тёплый и горячий запуск

Android определяет три сценария запуска — от самого медленного к самому быстрому:

  • Запуск с нуля: процесса ещё не существует. Android создаёт его, запускает Application, а затем первый экран. Это самый медленный сценарий и главный объект оптимизации.
  • Тёплый запуск: процесс работает, но Activity необходимо создать заново.
  • Горячий запуск: Activity всё ещё находится в памяти; нужно лишь вывести её на передний план. Почти мгновенно.

Основные усилия по оптимизации направлены на запуск с нуля, поскольку именно с ним чаще всего сталкиваются новые и возвращающиеся пользователи.

Измерение времени запуска

Невозможно улучшить то, что Вы не измеряете. Есть два простых способа:

  • Logcat: система записывает строку Displayed со временем до появления первого кадра.
  • Макротестирование производительности: StartupTimingMetric предоставляет стабильные и воспроизводимые значения для запуска с нуля.

Выполните приведённую ниже команду adb и найдите строку Displayed.

# Cold-start the app and log time to first frame
adb shell am start -W -S com.example.app/.MainActivity

# Output includes:
#   TotalTime: 412   <- ms to first frame
# Or filter logcat:
adb logcat | grep "Displayed com.example.app"

Сохраняйте лёгкость Application.onCreate

Всё, что выполняется в Application.onCreate(), запускается в главном потоке до появления первого кадра. Тяжёлая инициализация здесь напрямую замедляет запуск.

В неудачном варианте ниже несколько библиотек инициализируются заранее. Отложите или перенесите в фоновый поток всё, что не требуется для первого экрана.

// SLOW: blocks the first frame with eager init
class MyApp : Application() {
    override fun onCreate() {
        super.onCreate()
        Analytics.init(this)        // network, disk
        ImageLoader.preload(this)   // heavy
        Database.warmUp(this)       // disk I/O
    }
}
// Each of these adds milliseconds before the user sees anything.

Библиотека запуска приложения Jetpack

Библиотека запуска приложения заменяет несколько поставщиков содержимого библиотек (каждый из них требует времени) одним общим поставщиком и позволяет наглядно задавать порядок и зависимости инициализации.

Для каждого компонента Вы реализуете отдельный Initializer; библиотека запуска приложения выполняет их один раз в порядке зависимостей.

class AnalyticsInitializer : Initializer<Analytics> {
    override fun create(context: Context): Analytics {
        return Analytics.init(context.applicationContext)
    }
    // Runs after Logger is ready
    override fun dependencies() = listOf(LoggerInitializer::class.java)
}
// Registered via a single merged provider in the manifest,
// avoiding one ContentProvider per library.

Отложенная и фоновая инициализация

Ещё лучше, чем упорядочивать предварительную работу, — сократить её объём при запуске. Вот два приёма:

  • Отложенная инициализация: создавайте тяжёлые объекты при первом использовании с помощью конструкции Kotlin by lazy.
  • Фоновая инициализация: переносите инициализацию, не связанную с интерфейсом, из главного потока.

Теперь первый кадр не блокируется работой, которая пока не нужна пользователю.

class MyApp : Application() {
    // Built only when first accessed, not during onCreate
    val imageLoader by lazy { ImageLoader.build(this) }

    override fun onCreate() {
        super.onCreate()
        // Push non-critical setup off the main thread
        CoroutineScope(Dispatchers.Default).launch {
            Analytics.init(applicationContext)
        }
    }
}

AOT и JIT: почему первый запуск медленный

По умолчанию Android выполняет байт-код приложения, сочетая интерпретацию и компиляцию «точно вовремя» (JIT). При первом выполнении часто используемый код интерпретируется (медленно), и только позже среда выполнения компилирует его в машинный код.

Именно поэтому запуск с нуля и первая прокрутка ощущаются медленнее. Базовые профили решают эту проблему: они указывают устройству скомпилировать важный код заранее (AOT) во время установки.

Что такое базовый профиль

Базовый профиль — это список классов и методов, которые используются в важных пользовательских сценариях (при запуске и первой прокрутке). Вы поставляете его вместе с приложением; во время установки устройство заранее компилирует эти методы (AOT), поэтому уже при первом запуске они выполняются с машинной скоростью.

По данным Google, ускорение запуска часто составляет 20–40 %, при этом в код функций не требуется вносить изменений — нужен только профиль.

// build.gradle.kts
plugins { id("androidx.baselineprofile") }

dependencies {
    baselineProfile(project(":baselineprofile"))
}
// The generated profile ships as
//   assets/dexopt/baseline.prof
// and is applied automatically at install.

Создание базового профиля

Профиль создаётся с помощью небольшого теста, который выполняет критический сценарий на устройстве; инструменты записывают запущенные методы и создают файл профиля. Затем Вы добавляете его в систему контроля версий и выполняете повторную сборку.

Ниже приведён типичный генератор, который записывает запуск и прокрутку.

@RunWith(AndroidJUnit4::class)
class BaselineProfileGenerator {
    @get:Rule val rule = BaselineProfileRule()

    @Test
    fun generate() = rule.collect(packageName = "com.example.app") {
        pressHome()
        startActivityAndWait()
        // exercise the critical journey
        device.findObject(By.res("feed")).fling(Direction.DOWN)
    }
}
// Run the generateBaselineProfile Gradle task to produce the file.

Проверка результата

Всегда подтверждайте улучшение с помощью теста производительности, сравнивая запуск с применённым профилем и без него (CompilationMode.None и Partial с профилем).

Если Вы не проводите измерения, то не сможете доказать пользу профиля, а устаревший профиль даже может ухудшить результат. Создавайте его заново, когда важные участки кода значительно изменятся.

@Test
fun startupWithProfile() = rule.measureRepeated(
    packageName = "com.example.app",
    metrics = listOf(StartupTimingMetric()),
    iterations = 10,
    startupMode = StartupMode.COLD,
    compilationMode = CompilationMode.Partial() // uses the baseline profile
) {
    pressHome()
    startActivityAndWait()
}

План оптимизации запуска

Соберите всё в повторяемый план:

  • Измерьте запуск с нуля с помощью макротестирования производительности и adb am start -W.
  • Сократите работу в Application.onCreate: используйте by lazy для отложенной инициализации и перенесите работу из главного потока.
  • Используйте библиотеку запуска приложения, чтобы объединить поставщиков содержимого и упорядочить инициализацию.
  • Поставляйте базовый профиль для AOT-компиляции критического сценария.
  • Проверьте результат с помощью теста производительности и поддерживайте профиль актуальным.

Результат: быстрый первый кадр, который пользователи сразу замечают.

Быстрая проверка

Вы поставляете базовый профиль вместе с приложением. Что он в первую очередь делает для ускорения запуска?

Итоги: быстро с первого кадра

Вы научились оптимизировать запуск — самый заметный показатель производительности:

  • Оптимизируйте запуск с нуля; измеряйте его с помощью макротестирования производительности и adb am start -W.
  • Сохраняйте лёгкость Application.onCreate: используйте отложенную инициализацию и выполняйте фоновую работу, не связанную с интерфейсом.
  • Используйте библиотеку запуска приложения, чтобы объединить поставщиков и упорядочить инициализаторы.
  • Поставляйте базовый профиль, чтобы горячий код компилировался заранее (AOT) во время установки и выполнялся с машинной скоростью уже при первом запуске.
  • Всегда проверяйте результат с помощью теста производительности и поддерживайте профиль актуальным.

На этом завершается раздел «Оптимизация и профилирование производительности»: теперь Вы умеете измерять производительность, управлять рекомпозицией, исправлять утечки и ускорять запуск.

Часто задаваемые вопросы

Урок «Профили запуска и Baseline Profiles» бесплатный?

Да — полный текст урока «Профили запуска и Baseline Profiles» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Android Academy, подпишись на CoddyKit PRO. Курс Android Academy содержит 4 уроков всего.

Чему я научусь в уроке «Профили запуска и Baseline Profiles»?

Ускоряйте холодный запуск Ты практикуешь Android Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Android Academy?

Предыдущий опыт не требуется. Android Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.

Сколько времени занимает урок «Профили запуска и Baseline Profiles»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Android Academy?

Да. Каждый урок Android Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Измерение производительности
  2. Управление рекомпозицией
  3. Утечки памяти и исправления
  4. Профили запуска и Baseline Profiles
← Назад к Android Academy