핵심 경로를 미리 AOT 컴파일하도록 알려 주는 프로필.
왜 첫 실행이 느린가
ART 는 기본적으로 인터프리터로 시작하고, 자주 도는 코드만 JIT 으로 컴파일한다 → 첫 실행은 느리다
Baseline Profile 을 함께 배포하면
- 설치 시점에 그 목록의 메서드를 AOT 컴파일해 둔다
- 첫 실행부터 컴파일된 코드로 돈다
공식 수치로 시작 시간 약 30% 개선 사례가 보고된다
// baselineProfile 모듈에서 시나리오를 적으면 프로필이 생성된다
@Test fun generate() = baselineProfileRule.collect(packageName = "com.example") {
startActivityAndWait()
device.findObject(By.res("feed")).fling(Direction.DOWN) // 자주 쓰는 경로를 훑는다
}
결과가 src/main/baseline-prof.txt 로 들어가고 AAB 에 함께 담겨 배포된다
시작 시간의 세 종류
-
cold — 프로세스가 없는 상태에서 시작. 가장 느리고 가장 중요하다
-
warm — 프로세스는 살아 있고 Activity 만 다시 만든다
-
hot — 화면만 다시 앞으로 가져온다
-
Play Console 이 보는 것도 cold 시작이다
시작을 늦추는 흔한 원인
- Application.onCreate 에서 SDK 를 전부 초기화한다
- androidx.startup 으로 지연 초기화하거나 필요 시점으로 미룬다
- 메인 스레드에서 SharedPreferences · DB 를 읽는다
- 스플래시를 직접 구현해 화면을 두 번 만든다
- SplashScreen API 를 쓴다
- 첫 화면에서 큰 이미지를 디코딩한다
측정한다 — 추측하지 않는다
@Test fun startup() = benchmarkRule.measureRepeated(
packageName = "com.example",
metrics = listOf(StartupTimingMetric()),
iterations = 10,
startupMode = StartupMode.COLD
) { pressHome(); startActivityAndWait() }
도구 선택
Macrobenchmark 시작 시간 · 스크롤 잰크 (실제 앱을 띄워 측정)
Microbenchmark 함수 단위 성능
Perfetto / 시스템 추적 프레임 단위로 무엇이 오래 걸렸는지
Android Studio 프로파일러 CPU · 메모리 · 네트워크
반드시 릴리스 빌드로 측정한다 — 디버그 수치는 의미가 없다
면접 함정
- ❌ "Baseline Profile은 코드를 바꾼다" → 컴파일 대상 목록일 뿐이다. 동작은 그대로다.
- ❌ "프로필을 한 번 만들면 끝" → 코드가 바뀌면 낡는다. CI에서 주기적으로 재생성한다.
Startup Profile도 있다
- Baseline Profile — 무엇을 AOT 컴파일할지
- Startup Profile — DEX 안에서 클래스를 어떤 순서로 배치할지
시작 시 읽는 클래스를 앞쪽에 모으면 페이지 폴트가 줄어든다 둘 다 같은 도구로 함께 생성된다
스플래시를 직접 만들지 않는다
// 시스템 SplashScreen API
installSplashScreen().setKeepOnScreenCondition { viewModel.isLoading }
직접 SplashActivity 를 만들면
- Activity 를 두 번 만들고, 테마 전환이 깜빡이고, 시작이 오히려 늦어진다
setKeepOnScreenCondition 은 남용하면 시작이 느려 보인다 — "정말 없으면 화면을 못 그리는 것" 만 기다린다
초기화를 미룬다
// androidx.startup — 초기화 순서를 선언하고 지연시킨다
class AnalyticsInitializer : Initializer<Analytics> {
override fun create(ctx: Context) = Analytics.init(ctx)
override fun dependencies() = emptyList<Class<out Initializer<*>>>()
}
Application.onCreate 에 SDK 를 열 개 넣으면 그 합이 곧 시작 시간이다
- 첫 화면에 필요 없는 것은 전부 미룬다 (by lazy · 화면 진입 시)
- 광고·분석 SDK 가 특히 무겁다