Skip to content

Baseline Profiles

源:Android 官方文档 - Baseline Profiles overview

Baseline Profiles 通过 AOT (Ahead-Of-Time) 编译优化应用启动速度和运行时性能,减少卡顿。

什么是 Baseline Profiles

Baseline Profiles 是一个包含应用关键代码路径的文件,告诉 Android Runtime (ART) 哪些类和方法应该被 AOT 编译。

工作原理

  1. 在发布前生成 Baseline Profile
  2. 打包到 AAB/APK 中
  3. 安装后,ART 立即 AOT 编译这些代码
  4. 应用从首次启动就获得性能提升

性能提升

典型改进

  • 启动速度提升 30%+
  • 减少卡顿和掉帧
  • 降低 ANR 发生率
  • 提高用户留存率

适用场景

  • 应用启动流程
  • 屏幕导航
  • 列表滚动
  • 复杂UI渲染

快速开始

前置要求

最低版本要求

组件最低版本
AGP8.0.0
Kotlin1.9.0
Compose1.4.0
Gradle8.0

添加依赖

kotlin
plugins {
    id("androidx.baselineprofile") version "1.3.0"
}

dependencies {
    baselineProfile(project(":baselineprofile"))
}
kotlin
plugins {
    id("androidx.baselineprofile") version "1.3.0" apply false
}

创建 Baseline Profile 模块

新建模块

FileNewModuleBaseline Profile Generator

或手动创建:

kotlin
// baselineprofile/build.gradle.kts
plugins {
    id("com.android.test")
    kotlin("android")
    id("androidx.baselineprofile")
}

android {
    namespace = "com.example.baselineprofile"
    compileSdk = 34
    
    targetProjectPath = ":app"
    
    testOptions.managedDevices.devices {
        create("pixel6Api31") {
            device = "Pixel 6"
            apiLevel = 31
            systemImageSource = "aosp"
        }
    }
}

dependencies {
    implementation("androidx.benchmark:benchmark-macro-junit4:1.3.0")
    implementation("androidx.test.ext:junit:1.2.1")
    implementation("androidx.test.espresso:espresso-core:3.6.1")
    implementation("androidx.test.uiautomator:uiautomator:2.3.0")
}

编写 Profile 生成测试

kotlin
// baselineprofile/src/main/kotlin/BaselineProfileGenerator.kt
package com.example.baselineprofile

import androidx.benchmark.macro.junit4.BaselineProfileRule
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith

@RunWith(AndroidJUnit4::class)
class BaselineProfileGenerator {
    @get:Rule
    val rule = BaselineProfileRule()
    
    @Test
    fun generate() = rule.collect(
        packageName = "com.example.myapp",
        
        // 定义用户旅程
        profileBlock = {
            startActivityAndWait()
            
            // 应用启动后的操作
            device.waitForIdle()
            
            // 导航到主界面
            device.findObject(By.text("Home")).click()
            device.waitForIdle()
            
            // 滚动列表
            val list = device.findObject(By.res("recyclerView"))
            list.setGestureMargin(device.displayWidth / 5)
            list.fling(Direction.DOWN)
            device.waitForIdle()
            
            // 打开详情页
            device.findObject(By.text("Details")).click()
            device.waitForIdle()
        }
    )
}

生成 Baseline Profile

bash
# 生成 Baseline Profile
./gradlew :baselineprofile:pixel6Api31BaselineProfile

生成的文件位于:

app/src/main/baseline-prof.txt

Profile 文件格式

# baseline-prof.txt
HSPLcom/example/myapp/MainActivity;-><init>()V
HSPLcom/example/myapp/MainActivity;->onCreate(Landroid/os/Bundle;)V
PLcom/example/myapp/ui/HomeScreen;->HomeScreen()V
SPLandroidx/compose/runtime/ComposerKt;->sourceInformation(...)V

标记说明

  • H - Hot method(热方法)- 应该被 AOT 编译
  • S - Startup method(启动方法)- 应用启动时调用
  • P - Post-startup method(启动后方法)
  • L - Layout(布局)- 在首帧绘制前编译

配置选项

变体配置

为不同构建变体生成不同的 Profile:

kotlin
android {
    defaultConfig {
        // ...
    }
}

baselineProfile {
    variants {
        release {
            automaticGenerationDuringBuild = true
        }
    }
    
    saveInSrc = true
    baselineProfileOutputDir = "."
}

Gradle Managed Devices

使用虚拟设备自动化生成:

kotlin
android {
    testOptions {
        managedDevices {
            devices {
                create<com.android.build.api.dsl.ManagedVirtualDevice>("pixel6Api31") {
                    device = "Pixel 6"
                    apiLevel = 31
                    systemImageSource = "aosp"
                }
            }
        }
    }
}

运行:

bash
./gradlew :baselineprofile:pixel6Api31BaselineProfile

自动生成

在构建时自动生成(不推荐用于 CI):

kotlin
baselineProfile {
    automaticGenerationDuringBuild = true
}

验证效果

使用 Macrobenchmark

创建基准测试验证改进:

kotlin
@RunWith(AndroidJUnit4::class)
class StartupBenchmark {
    @get:Rule
    val rule = MacrobenchmarkRule()
    
    @Test
    fun startupNoCompilation() = startup(CompilationMode.None())
    
    @Test
    fun startupBaselineProfile() = startup(CompilationMode.Partial(
        baselineProfileMode = BaselineProfileMode.Require
    ))
    
    private fun startup(compilationMode: CompilationMode) = rule.measureRepeated(
        packageName = "com.example.myapp",
        metrics = listOf(StartupTimingMetric()),
        iterations = 5,
        compilationMode = compilationMode
    ) {
        pressHome()
        startActivityAndWait()
    }
}

对比结果:

startupNoCompilation: 450ms
startupBaselineProfile: 310ms  # 31% 提升

分析生成的 Profile

查看类覆盖率

bash
# 查看有多少类被包含
grep -c '^H' app/src/main/baseline-prof.txt

热方法分析

bash
# 查看所有热方法
grep '^H' app/src/main/baseline-prof.txt | head -20

最佳实践

Profile 应该包含什么

√ 应该包含

  • 应用启动流程
  • 常见用户操作
  • 关键用户旅程
  • 首屏渲染

× 不应该包含

  • 很少使用的功能
  • 错误处理路径
  • 调试代码

增量更新

每次发布前更新 Profile:

bash
./gradlew :baselineprofile:generateBaselineProfile

提交更新的 baseline-prof.txt 到版本控制。

多变体支持

为不同产品变体生成不同的 Profile:

kotlin
android {
    productFlavors {
        create("free") {
            // ...
        }
        create("paid") {
            // ...
        }
    }
}

// 分别生成
// ./gradlew :baselineprofile:freeReleaseBaselineProfile
// ./gradlew :baselineprofile:paidReleaseBaselineProfile

CI/CD 集成

在 CI 中验证 Profile 存在:

yaml
# GitHub Actions 示例
- name: Verify Baseline Profile
  run: |
    if [ ! -f "app/src/main/baseline-prof.txt" ]; then
      echo "Baseline Profile not found!"
      exit 1
    fi

监控 Profile 效果

使用 Firebase Performance Monitoring 或自定义分析:

kotlin
val trace = FirebasePerformance.getInstance().newTrace("app_start")
trace.start()
// 应用启动逻辑
trace.stop()

Baseline Profiles vs Startup Profiles

特性Baseline ProfilesStartup Profiles
生成方式开发者生成并打包到应用Google Play 自动生成
生效时间首次安装即生效需要用户使用一段时间
覆盖范围开发者定义的用户旅程基于真实用户行为
控制力完全由开发者控制Google 自动优化
适用场景所有分发渠道仅 Google Play

建议:同时使用两者获得最佳效果。

Cloud Profiles

Google Play 自动生成的 Profile,基于真实用户行为。

启用方式

在 Google Play Console 中默认启用,无需额外配置。

与 Baseline Profiles 的关系

  • Baseline Profiles 保证首次安装即优化
  • Cloud Profiles 基于真实数据持续优化
  • 两者互补,不冲突

常见问题

Profile 文件太大

问题:生成的 Profile 过大,增加 APK 体积。

解决

  • 精简用户旅程
  • 移除不常用的功能
  • 检查是否包含第三方库代码

性能提升不明显

可能原因

  • Profile 覆盖的代码路径不是瓶颈
  • 设备已有足够的 JIT 优化
  • Profile 生成不完整

解决

  • 使用 Profiler 分析实际瓶颈
  • 确保 Profile 覆盖关键路径
  • 在低端设备上测试

构建时间增加

原因:自动生成 Profile 需要运行测试。

解决

  • 关闭 automaticGenerationDuringBuild
  • 仅在发布前手动生成
  • 使用增量生成

工具链

AGP Baseline Profile Plugin

  • 自动集成 Profile 到构建
  • 支持多变体
  • Gradle Managed Devices 支持

Macrobenchmark

  • 生成 Profile
  • 性能基准测试
  • 对比优化效果

Android Studio Profiler

  • 分析启动性能
  • 验证 AOT 编译
  • 识别优化机会