기준 프로필 만들기

Jetpack Macrobenchmark 라이브러리BaselineProfileRule을 사용하여 각 앱 버전에 맞는 프로필을 자동으로 생성하세요. 기준 프로필을 사용할 때는 빌드 개선사항이 적용된 com.android.tools.build:gradle:8.0.0 이상을 사용하는 것이 좋습니다.

다음은 새 기준 프로필을 만드는 일반적인 단계입니다.

  1. 기준 프로필 모듈을 설정합니다.
  2. 기준 프로필 생성에 도움이 되는 JUnit 테스트를 정의합니다.
  3. 최적화할 중요한 사용자 여정(CUJ)을 추가합니다.
  4. 기준 프로필을 생성합니다.

기준 프로필을 생성한 후 실제 기기를 사용하여 이를 벤치마킹해 속도 개선을 측정합니다.

AGP 8.2 이상을 사용하여 새 기준 프로필 만들기

새 기준 프로필을 만드는 가장 쉬운 방법은 Android 스튜디오 Iguana 및 Android Gradle 플러그인(AGP) 8.2부터 사용할 수 있는 기준 프로필 모듈 템플릿을 사용하는 것입니다.

Android 스튜디오 기준 프로필 생성기 모듈 템플릿은 새 모듈 생성을 자동화하여 기준 프로필을 생성하고 이를 벤치마킹합니다. 이 템플릿을 실행하면 대부분의 일반 빌드 구성과 기준 프로필 생성, 인증 코드가 생성됩니다. 템플릿은 앱 시작을 측정하기 위한 기준 프로필을 생성하고 벤치마킹하는 코드를 생성합니다.

기준 프로필 모듈 설정

기준 프로필 모듈 템플릿을 실행하려면 다음 단계를 따르세요.

  1. File > New > New Module을 선택합니다.
  2. Templates 패널에서 Baseline Profile Generator 템플릿을 선택하고 구성합니다.
    그림 1. 기준 프로필 생성기 모듈 템플릿

    템플릿의 필드는 다음과 같습니다.

    • Target application: 기준 프로필이 생성되는 앱을 정의합니다. 프로젝트에 앱 모듈이 하나만 있는 경우 이 목록에는 항목이 하나만 있습니다.
    • Module name: 만드는 기준 프로필 모듈에 사용할 이름입니다.
    • Package name: 기준 프로필 모듈에 사용할 패키지 이름입니다.
    • Language: 생성된 코드가 Kotlin인지 Java인지를 나타냅니다.
    • Build configuration language: 빌드 구성 스크립트에 Kotlin 스크립트(KTS)를 사용할지, Groovy를 사용할지를 나타냅니다.
    • Gradle 관리 기기 사용: 앱을 테스트하는 데 Gradle 관리 기기를 사용하는지 여부입니다.
  3. Finish를 클릭하면 새 모듈이 생성됩니다. 소스 제어를 사용하는 경우 새로 만든 모듈 파일을 소스 제어에 추가하라는 메시지가 표시될 수 있습니다.

기준 프로필 생성기 정의

새로 만든 모듈에는 기준 프로필을 생성 및 벤치마킹하고 기본 앱 시작만 테스트하기 위한 테스트가 포함되어 있습니다. CUJ 및 고급 시작 워크플로를 포함하도록 이를 보강하는 것이 좋습니다. 앱 시작과 관련된 테스트는 includeInStartupProfiletrue로 설정된 rule 블록에 있어야 합니다. 반대로 최적의 성능을 위해서는 앱 시작과 관련 없는 테스트가 시작 프로필에 포함되지 않도록 해야 합니다. 앱 시작 최적화는 시작 프로필이라고 하는 기준 프로필의 특별한 부분을 정의하는 데 사용됩니다.

이렇게 하면 생성된 기준 프로필과 벤치마크 코드를 벗어나 CUJ를 추상화하더라도 CUJ를 두 가지 모두에 사용할 수 있으므로 유지관리에 도움이 됩니다. 따라서 CUJ의 변경사항이 일관되게 사용됩니다.

기준 프로필 생성 및 설치

기준 프로필 모듈 템플릿은 기준 프로필을 생성하기 위한 새로운 실행 구성을 추가합니다. 제품 버전을 사용하는 경우 Android 스튜디오는 여러 실행 구성을 생성하므로, 버전별로 별도의 기준 프로필을 생성할 수 있습니다.

기준 프로필 생성 실행 구성
그림 2. 이 구성을 실행하면 기준 프로필이 생성됩니다.

Generate Baseline Profile 실행 구성이 완료되면 생성된 기준 프로필을 프로파일링 중인 모듈의 src/variant/generated/baselineProfiles/baseline-prof.txt 파일에 복사합니다. 변형 옵션은 출시 빌드 유형 또는 출시 빌드 유형과 관련된 빌드 변형입니다.

생성된 기준 프로필은 원래 build/outputs에서 만들어집니다. 전체 경로는 프로파일링 중인 앱의 변형이나 버전, 그리고 Gradle 관리 기기와 연결된 기기 중 어떤 기기가 프로파일링에 사용되는지에 따라 결정됩니다. 코드에 사용된 이름과 템플릿에서 생성된 빌드 구성을 사용하는 경우 기준 프로필은 build/outputs/managed_device_android_test_additional_output/nonminifiedrelease/pixel6Api31/BaselineProfileGenerator_generate-baseline-prof.txt 파일에 생성됩니다. 생성된 기준 프로필의 이 버전과 직접 상호작용하지 않아도 됩니다. 단, 타겟 모듈에 수동으로 복사하는 경우(권장하지 않음)는 예외입니다.

AGP 8.1을 사용하여 새 기준 프로필 만들기

기준 프로필 모듈 템플릿을 사용할 수 없다면 Macrobenchmark 모듈 템플릿과 기준 프로필 Gradle 플러그인을 사용하여 새 기준 프로필을 만드세요. Android 스튜디오 Giraffe 및 AGP 8.1부터 이러한 도구를 사용하는 것이 좋습니다.

다음은 Macrobenchmark 모듈 템플릿과 기준 프로필 Gradle 플러그인을 사용하여 새 기준 프로필을 만드는 단계입니다.

  1. Gradle 프로젝트에서 Macrobenchmark 모듈을 설정합니다.
  2. BaselineProfileGenerator라는 새 클래스를 정의합니다.
    class BaselineProfileGenerator {
        @get:Rule
        val baselineProfileRule = BaselineProfileRule()
    
        @Test
        fun startup() = baselineProfileRule.collect(
            packageName = "com.example.app",
            profileBlock = {
                startActivityAndWait()
            }
        )
    }
    

    생성기에는 앱 시작 이후에 발생하는 앱과의 상호작용이 포함될 수 있습니다. 이를 통해 목록 스크롤, 애니메이션 실행, Activity 내 탐색과 같은 앱의 런타임 성능을 최적화할 수 있습니다. @BaselineProfileRule을 사용하여 중요한 사용자 여정을 개선하는 다른 테스트 예제를 살펴보세요.

  3. 기준 프로필 Gradle 플러그인(libs.plugins.androidx.baselineprofile)을 추가합니다. 플러그인을 사용하면 더 쉽게 기준 프로필을 생성하고 향후 유지관리할 수 있습니다.

  4. 기준 프로필을 생성하려면 터미널에서 :app:generateBaselineProfile 또는 :app:generateVariantBaselineProfile Gradle 작업을 실행합니다.

    루팅된 실제 기기, 에뮬레이터 또는 Gradle 관리 기기에서 계측 테스트로 생성기를 실행합니다. Gradle 관리 기기를 사용하는 경우 기준 프로필 생성기에 대한 루트 액세스 권한이 필요하므로 aospsystemImageSource로 설정합니다.

    생성 작업이 끝나면 기준 프로필이 app/src/variant/generated/baselineProfiles에 복사됩니다.

템플릿 없이 새 기준 프로필 만들기

Android 스튜디오 기준 프로필 모듈 템플릿(권장) 또는 Macrobenchmark 템플릿을 사용하여 기준 프로필을 만드는 것이 좋지만 기준 프로필 Gradle 플러그인만 사용해도 됩니다. 기준 프로필 Gradle 플러그인에 관한 자세한 내용은 기준 프로필 생성 구성을 참고하세요.

다음은 기준 프로필 Gradle 플러그인을 직접 사용하여 기준 프로필을 만드는 방법입니다.

  1. com.android.test 모듈을 만듭니다(예: :baseline-profile).
  2. :baseline-profilebuild.gradle.kts 파일을 구성합니다.

    1. androidx.baselineprofile 플러그인을 적용합니다.
    2. targetProjectPath:app 모듈을 가리키도록 합니다.
    3. 필요한 경우 Gradle 관리 기기(GMD)를 추가합니다. 다음 예에서는 pixel6Api31입니다. 지정하지 않으면 플러그인이 연결된 기기(에뮬레이션 기기 또는 실제 기기)를 사용합니다.
    4. 다음 예와 같이 원하는 구성을 적용합니다.

    Kotlin

    plugins {
        id("com.android.test")
        id("androidx.baselineprofile")
    }
    
    android {
        defaultConfig {
            ...
        }
    
        // Point to the app module, the module that you're generating the Baseline Profile for.
        targetProjectPath = ":app"
        // Configure a GMD (optional).
        testOptions.managedDevices.devices {
            pixel6Api31(com.android.build.api.dsl.ManagedVirtualDevice) {
                device = "Pixel 6"
                apiLevel = 31
                systemImageSource = "aosp"
            }
        }
    }
    
    dependencies { ... }
    
    // Baseline Profile Gradle plugin configuration. Everything is optional. This
    // example uses the GMD added earlier and disables connected devices.
    baselineProfile {
        // Specifies the GMDs to run the tests on. The default is none.
        managedDevices += "pixel6Api31"
        // Enables using connected devices to generate profiles. The default is
        // `true`. When using connected devices, they must be rooted or API 33 and
        // higher.
        useConnectedDevices = false
    }
    

    Groovy

    plugins {
        id 'com.android.test'
        id 'androidx.baselineprofile'
    }
    
    android {
        defaultConfig {
            ...
        }
    
        // Point to the app module, the module that you're generating the Baseline Profile for.
        targetProjectPath ':app'
        // Configure a GMD (optional).
        testOptions.managedDevices.devices {
            pixel6Api31(com.android.build.api.dsl.ManagedVirtualDevice) {
                device 'Pixel 6'
                apiLevel 31
                systemImageSource 'aosp'
            }
        }
    }
    
    dependencies { ... }
    
    // Baseline Profile Gradle plugin configuration. Everything is optional. This
    // example uses the GMD added earlier and disables connected devices.
    baselineProfile {
        // Specifies the GMDs to run the tests on. The default is none.
        managedDevices ['pixel6Api31']
        // Enables using connected devices to generate profiles. The default is
        // `true`. When using connected devices, they must be rooted or API 33 and
        // higher.
        useConnectedDevices false
    }
    
  3. :baseline-profile 테스트 모듈에서 기준 프로필 테스트를 만듭니다. 다음 예는 앱을 시작하고 유휴 상태를 기다리는 테스트입니다.

    Kotlin

    class BaselineProfileGenerator {
    
        @get:Rule
        val baselineRule = BaselineProfileRule()
    
        @Test
        fun startupBaselineProfile() {
            baselineRule.collect("com.myapp") {
                startActivityAndWait()
            }
        }
    }
    

    Java

    public class BaselineProfileGenerator {
    
        @Rule
        Public BaselineProfileRule baselineRule = new BaselineProfileRule();
    
        @Test
        Public void startupBaselineProfile() {
            baselineRule.collect(
                "com.myapp",
                (scope -> {
                    scope.startActivityAndWait();
                    Return Unit.INSTANCE;
                })
            )
        }
    }
    
  4. 앱 모듈(예: :app)에서 build.gradle.kts 파일을 업데이트합니다.

    1. androidx.baselineprofile 플러그인을 적용합니다.
    2. :baseline-profile 모듈에 baselineProfile 종속 항목을 추가합니다.

    Kotlin

    plugins {
        id("com.android.application")
        id("androidx.baselineprofile")
    }
    
    android {
        // There are no changes to the `android` block.
        ...
    }
    
    dependencies {
        ...
        // Add a `baselineProfile` dependency on the `:baseline-profile` module.
        baselineProfile(project(":baseline-profile"))
    }
    

    Groovy

    plugins {
        id 'com.android.application'
        id 'androidx.baselineprofile'
    }
    
    android {
        // No changes to the `android` block.
        ...
    }
    
    dependencies {
        ...
        // Add a `baselineProfile` dependency on the `:baseline-profile` module.
        baselineProfile ':baseline-profile"'
    }
    
  5. :app:generateBaselineProfile 또는 :app:generateVariantBaselineProfile Gradle 작업을 실행하여 프로필을 생성합니다.

  6. 생성 작업이 끝나면 기준 프로필이 app/src/variant/generated/baselineProfiles에 복사됩니다.

AGP 7.3~7.4를 사용하여 새 기준 프로필 만들기

AGP 7.3~7.4로 기준 프로필을 생성할 수 있지만, 기준 프로필 Gradle 플러그인과 그 최신 기능을 사용할 수 있도록 AGP 8.1 이상으로 업그레이드하는 것이 좋습니다.

AGP 7.3~7.4를 사용하여 기준 프로필을 만들어야 하는 경우 단계는 AGP 8.1의 단계와 동일하지만 다음과 같은 예외가 있습니다.

  • 기준 프로필 Gradle 플러그인을 추가하지 않습니다.
  • 기준 프로필을 생성하려면 Gradle 작업 ./gradlew [emulator name][flavor][build type]AndroidTest를 실행합니다. 예를 들면 다음과 같습니다. ./gradlew :benchmark:pixel6Api31BenchmarkAndroidTest
  • 생성된 기준 프로필 규칙을 코드에 직접 적용해야 합니다.

생성된 규칙 직접 적용

기준 프로필 생성기가 기기에 인간이 읽을 수 있는 형식(HRF)의 텍스트 파일을 만들어 해당 파일을 호스트 머신에 복사합니다. 생성된 프로필을 코드에 적용하려면 다음 단계를 따르세요.

  1. 프로필을 생성하는 모듈의 빌드 폴더([module]/build/outputs/managed_device_android_test_additional_output/[device])에서 HRF 파일을 찾습니다.

    프로필은 [class name]-[test method name]-baseline-prof.txt와 같은 이름 지정 패턴을 따릅니다(예: BaselineProfileGenerator-startup-baseline-prof.txt).

  2. 생성된 프로필을 src/main/에 복사하고 파일 이름을 baseline-prof.txt로 바꿉니다.

  3. 클라우드 프로필을 사용할 수 없는 경우 로컬 기준 프로필 컴파일을 사용할 수 있도록 앱의 build.gradle.kts 파일에 ProfileInstaller 라이브러리에 관한 종속 항목을 추가합니다. 이는 로컬에서 기준 프로필을 사이드로드하는 유일한 방법입니다.

    dependencies {
         implementation("androidx.profileinstaller:profileinstaller:1.3.1")
    }
    
  4. 적용된 HRF 규칙이 바이너리 형식으로 컴파일되어 APK 또는 AAB에 포함되는 동안 앱의 프로덕션 버전을 빌드합니다. 그런 다음 평소 앱을 배포하던 방식으로 앱을 배포합니다.

기준 프로필 벤치마킹하기

기준 프로필을 벤치마킹하려면 StartupBenchmarks.kt 또는 StartupBencharks.java 파일에 정의된 벤치마크를 실행하는 여백 작업에서 새로운 Android 계측 테스트 실행 구성을 만듭니다. 벤치마크 테스트에 관한 자세한 내용은 Macrobenchmark 클래스 만들기Macrobenchmark 라이브러리를 사용하여 측정 자동화를 참고하세요.

그림 3. 여백 작업에서 Android 테스트를 실행합니다.

Android 스튜디오에서 이를 실행하면 빌드 출력에 기준 프로필이 제공하는 속도 향상에 관한 세부정보가 포함됩니다.

StartupBenchmarks_startupCompilationBaselineProfiles
timeToInitialDisplayMs   min 161.8,   median 178.9,   max 194.6
StartupBenchmarks_startupCompilationNone
timeToInitialDisplayMs   min 184.7,   median 196.9,   max 202.9

필요한 모든 코드 경로 캡처하기

앱 시작 시간을 측정하는 두 가지 주요 측정항목은 다음과 같습니다.

처음 표시하는 데 걸린 시간(TTID)
애플리케이션 UI의 첫 번째 프레임을 표시하는 데 걸리는 시간입니다.
완전히 표시하는 데 걸린 시간(TTFD)
TTID와 첫 번째 프레임이 표시된 후 비동기식으로 로드되는 콘텐츠 표시 시간을 더한 값입니다.

TTFD는 ComponentActivityreportFullyDrawn() 메서드가 호출되면 보고됩니다. reportFullyDrawn()이 호출되지 않은 경우 대신 TTID가 보고됩니다. reportFullyDrawn()이 호출되는 시점을 비동기 로드가 완료된 후로 지연해야 할 수도 있습니다. 예를 들어, UI에 RecyclerView 또는 지연 목록과 같은 동적 목록이 포함되어 있는 경우 목록이 처음 그려진 후에 완료되는, 즉 UI가 완전히 그려진 것으로 표시된 후에 완료되는 백그라운드 작업으로 채워질 수 있습니다. 이 경우 UI가 완전히 그려진 상태에 도달한 후에 실행되는 코드는 기준 프로필에 포함되지 않습니다.

기준 프로필의 일부로 목록 채우기를 포함하려면 getFullyDrawnReporter()를 사용하여 FullyDrawnReporter를 가져오고 앱 코드에서 여기에 리포터를 추가합니다. 백그라운드 작업이 목록 채우기를 완료하면 리포터를 해제합니다. FullyDrawnReporter는 모든 리포터가 해제될 때까지 reportFullyDrawn() 메서드를 호출하지 않습니다. 이렇게 하면 기준 프로필에 목록을 채우는 데 필요한 코드 경로가 포함됩니다. 이렇게 해도 사용자에게 보여지는 앱 동작은 변하지 않지만, 기준 프로필은 필요한 모든 코드 경로를 갖게 됩니다.

앱에서 Jetpack Compose를 사용하는 경우 다음 API를 사용하여 완전히 그려진 상태를 표시합니다.

  • ReportDrawn: 구성 가능한 함수가 즉시 상호작용할 준비가 되었음을 나타냅니다.
  • ReportDrawnWhen: 구성 가능한 함수가 상호작용할 준비가 되었음을 나타내는 조건자(예: list.count > 0)를 받습니다.
  • ReportDrawnAfter: 완료 시 구성 가능한 함수와 상호작용할 준비가 되었음을 나타내는 정지 메서드를 받습니다.