안녕하세요. 이번 글에서는 '앱 시작 시간'에 대해서 알아보려고 합니다.
앱 시작 시간은 앱 성능 지표 중 하나인데요. 최근 면접에서 앱 시작 시간에 대한 질문에 대답을 못했어요 하하,, 이번 기회에 한번 같이 알아보면 좋을 것 같죠?
앱 시작 시간이란?
앱 시작 시간은 Android 성능 지표 중 하나로 앱을 로드하는 시간을 의미해요. 구글에서는 사용자의 경험을 위해 앱 시작 시간을 개선하라고 적극 권장하고 있는데요. Google Photo 앱에 시작 시간을 35 퍼 빠르도록 개선했다는 발표도 있었습니다
앱 시작 시간 유형
구글은 앱이 실행되기 전 상태에 따라서 앱 시작 시간 유형을 구분했습니다.
Cold Start
Cold Start는 앱이 처음부터 시작하는 것을 의미합니다. 기기가 부팅되고 맨 처음 실행되거나 시스템에서 앱을 완전히 종료한 이후 앱이 실행될 때 해당합니다. 이 유형은 처음부터 모든 과정을 수행하는 작업이기 때문에 가장 많은 시간이 소요되는 유형이라고 합니다.
Cold Start를 시작할 때 시스템은 다음과 같은 세 가지 작업을 실행한다고 합니다.
- 앱 로드 및 실행
- 실행 직후 앱의 빈 시작 창 표시
- 앱 프로세스 만들기
앱 로드 및 실행 단계는 앱 아이콘을 누른 시점에 실행에 필요한 리소스, 그리고 클래스 정보를 시스템 프로세스 메모리에 로드하는 것을 의미합니다. 메모리에 정상적으로 로드가 되면 시스템은 앱 프로세스를 생성하고 초기화를 진행합니다.
시스템에서 앱 프로세스를 만들면 진행하는 과정은 다음과 같습니다
- Application 객체 만들기
- Main Thread 실행
- Activity 생성
- View Inflate
- View Layout 배치
- View OnDraw
Manifest의 android:name 속성으로 Application 클래스를 자체 구현하는 경우, onCreate 함수에서 많은 작업을 수행한다면 앱 시작 시간 증가의 원인이 될 수 있어 주의해야 합니다.
Warm Start
Warm Start는 Cold Start와 달리 앱 프로세스는 이미 존재하는 상황에서 앱이 실행되는 유형입니다. 그래서 Cold Start의 작업 중 프로세스 생성 이후 작업인 앱 초기화부터 진행됩니다. Warm Start로 실행되는 기본적인 상태는 다음과 같다고 합니다
- 시스템이 아닌 사용자가 앱을 종료한 다음 다시 실행한 경우
- 시스템이 메모리에서 앱을 제거한 다음 사용자가 앱을 다시 시작한 경우
Hot Start
Hot Start는 백그라운드에 있던 Activity를 포그라운드로 올리는 유형을 의미합니다.
Activity를 포그라운드로 다시 올리는 것이기 때문에 객체 초기화, 레이아웃 확장, 렌더링을 다시 진행하지 않지만, 메모리의 유실이 있는 경우 다시 초기화부터 진행될 수 있다고 합니다. 예를 들어, 백그라운드에서 부족한 메모리 공간을 늘리기 위해 캐시 된 데이터, 비트맵 이미지 또는 사용하지 않는 리소스를 반환을 한 경우를 의미합니다.
Android 게임에서의 시작 유형
이 주제를 공부하면서 Android Game에서는 추가적인 시작 유형이 있다는 것을 알게 되었습니다.
- 첫 번째 로드
- 레벨 간 로드
Game은 일반적인 Android 앱과 달리 리소스를 다운로드하는 등 특수한 이벤트가 있기 때문이라고 해요. 그래서 신기하고 재밌었어요. 관련 자세한 내용은 이 링크에서 확인해 보시면 좋을 것 같네요 https://support.google.com/googleplay/android-developer/answer/10911598?hl=ko
앱 시작 시간의 측정 항목
시간을 말 그대로 측정하기 위해서는 시작과 끝이 있어야 합니다. 처음 시간을 측정하는 시작은 앞서 다룬 시작 유형에 따라서 달라집니다. Cold Start는 앱 로드부터, Warm Start 또는 Hot Start는 Activity 초기화부터 시간을 측정합니다.
그리고 측정을 마치는 기준은 두 가지가 있습니다. 처음 표시하는 데 걸린 시간(TTID)과 완전히 표시하는 데 걸린 시간(TTFD)입니다.
TTID
TTID는 앱이 시작되고 첫 프레임이 표시되기까지 걸리는 시간을 의미합니다. Google Play Console 등 앱 시작 시간을 측정하고 경고해 주는 기능들은 대부분 TTID를 기준으로 측정한다고 합니다.
TTID는 Logcat에서 Displayed로 시작되는 로그를 통해 확인할 수 있습니다. TTID를 확인하기 위해서는 filter에서 앱 패키지를 제거해야 볼 수 있어요. 이는 측정하는 주최가 시스템이기 때문입니다.
로그에서는 현재 측정한 시간이 Cold인지 Wram 인지 알 수 없다는 아쉬움이 있었습니다.
TTFD
TTFD는 첫번 째 프레임 이후 비동기 작업을 통해 로드한 데이터를 포함한 첫 프레임이 노출되기까지 걸리는 시간을 의미합니다. TTFD는 기본적으로 측정되지 않으며 ComponentActivity의 reportFullyDrawn() 함수를 호출하여 측정될 수 있습니다.
앱 시작 시간 개선
측정한 시간 어느 정도로 개선해야 할까요? 구글 공식 문서에서 각 시작 유형 별로 최소 시간을 정해주지는 않았지만 Android vitals에 따르면 시작 유형별로 권장되는 시간은 다음과 같다고 합니다.
만약 Android vitals 정한 시간보다 오래 걸린다면 어떻게 개선할 수 있을까요? 구글 공식 문서에 설명한 몇 가지 부분만 골라 보았어요.
크거나 복잡한 레이아웃 확장
Google은 중첩된 레이아웃 구조를 단순한 레이아웃 구조로 만들어주는 새로운 레이아웃인 ConstraintLayout 소개했었습니다. 중첩된 레이아웃 구조가 성능에 안 좋은 점은 이 공식 블로그에서 소개하고 있으니 한번 읽어보셔도 좋을 것 같습니다. 그래서 결론은 복잡한 레이아웃이 있다면 ConstraintLayout으로 변경하자!
Splash API 사용
공식문서에 따르면 Splash를 구현하기 위해 사용했던 다음 두 가지 방법은 시작 시간을 지연시킬 수 있다고 합니다.
- windowDisablePreview 속성을 true로 해서 background 속성으로 Splash Drawable을 표시
- Custom Splash Activity 사용
첫 번째 케이스의 경우, 가벼운 Preview가 아닌 이미지가 포함된 Drawable을 그리느라 시간이 경과될 수 있을 것 같다고 이해가 되었는데요. 두 번째 케이스는 짐작이긴 하지만 setContentView를 하지 않고 Theme를 코드로 설정해서 Splash를 구현한 경우가 아닐까 의심이 되네요
아무튼 Splash API를 통해 Splash를 구현하는 것이 시작 시간이 개선이 된다고 하네요.
이 밖에도 과도한 초기화, I/O 작업 등 시작 시간을 지연시키는 요소에 대해서 공식 문서에서 잘 설명해주고 있으니 심심하면 한번 보시는 것을 추천드립니다. 모르는 개념들이 너무나 많네~~
참고
- https://developer.android.com/topic/performance/vitals/launch-time?hl=ko
'Android > Common' 카테고리의 다른 글
[Android] touchDelegate로 뷰 계층 제약 없이 터치 영역 확장하기 (1) | 2023.11.30 |
---|---|
[Android] InAppUpdate 기능 알아보기 (1) | 2023.11.09 |
[Android] minSdk, compileSdk, targetSdk (0) | 2023.09.25 |
[Android] Radius 올바르게 적용하기 (0) | 2023.05.24 |
[Android] Fragment에서 데이터 외부로 전달시키는 방법 - ActivityViewModel (0) | 2022.12.06 |