일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 큐 자바 코드
- ar vr 차이
- rxjava hot observable
- rxjava disposable
- 객체
- Rxjava Observable
- 자바 다형성
- 서비스 쓰레드 차이
- 2022 플러터 안드로이드 스튜디오
- jvm 작동 원리
- 스택 자바 코드
- 스택 큐 차이
- 안드로이드 레트로핏 crud
- 안드로이드 레트로핏 사용법
- ANR이란
- android retrofit login
- 2022 플러터 설치
- 멤버변수
- 서비스 vs 쓰레드
- 클래스
- 안드로이드 라이선스 종류
- 플러터 설치 2022
- jvm이란
- 안드로이드 유닛 테스트
- android ar 개발
- 안드로이드 os 구조
- 안드로이드 라이선스
- 안드로이드 유닛 테스트 예시
- rxjava cold observable
- 안드로이드 유닛테스트란
- Today
- Total
나만을 위한 블로그
[Android] FirebasePerformance란? FirebasePerformance 사용법 본문
열심히 앱을 만들었어도 속도 등 앱의 성능이 눈물날 정도로 좋지 않을 수 있다. 게다가 안드로이드의 경우 아이폰보다 더 다양한 종류와 메이커가 존재하기 때문에 물리적으로 모든 테스트 기기를 준비해서 성능 테스트를 할 순 없다. 그리고 IDE가 제공하는 성능 측정만으로는 부족할 수도 있다.
이 때 앱 개발자들의 만만한 친구인 파이어베이스가 제공하는 Performance Monitoring을 사용해서 앱 성능을 측정하고 결과를 시각화해서 볼 수 있다.
공식문서에서는 Performance Monitoring을 뭐라고 설명하는지 확인해 본다.
https://firebase.google.com/docs/perf-mon?hl=ko
Firebase Performance Monitoring은 애플, 안드로이드, 웹 앱의 성능 특성을 파악하는 데 도움이 되는 서비스다. Performance Monitoring SDK를 써서 앱에서 성능 데이터를 수집하고 파이어베이스 콘솔에서 데이터를 검토, 분석한다. Performance Monitoring을 통해 앱 성능을 개선할 수 있는 부분을 실시간으로 파악해서 성능 문제를 해결할 수 있다
< 주요 기능 >
1. 앱 시작 시간, HTTP 네트워크 요청 등을 자동 측정 : 코드를 작성할 필요 없이 앱 성능을 크게 좌우하는 여러 요소에 대한 모니터링을 시작할 수 있다. 네이티브 앱의 경우 SDK는 시작 시간, 화면별 렌더링 데이터, 포그라운드 액티비티, 백그라운드 활동을 로깅한다. 웹 앱의 경우 SDK는 컨텐츠가 포함된 첫 페인트, 유저가 앱과 상호작용하는 기능 등의 요소를 로깅한다
2. 앱 성능을 개선할 수 있는 상황 파악 : 성능 측정항목을 국가, 기기, 앱 버전, OS 수준 등 속성에 따라 분류해서 파악할 수 있다
3. 앱 모니터링 맞춤설정 : 커스텀 코드 Trace를 계측하면 새 화면을 불러오거나 새 상호작용 기능을 표시할 때와 같은 특정 상황의 앱 성능을 캡쳐할 수 있다. 또한 이런 Trace를 수집하면서 직접 정의한 이벤트(캐시 적중 등)를 계수하는 커스텀 측정 항목을 커스텀 코드 Trace에서 만들 수 있다
4. 앱 성능의 큰 변화 파악 : 앱을 성공적으로 운영하려면 네트워크 중단 같은 주요 앱 성능 문제를 파악하고 해결하는 게 매우 중요하다. Performance Monitoring을 쓰면 앱의 가장 중요한 부분에 대한 알림을 설정하고 맞춤설정해서 문제가 유저에게 영향을 주기 전에 성능 문제를 발견하고 대응할 수 있다
이 밑의 기본 원리 챕터에 앱 시작 시간, 화면 렌더링 등의 문서가 있으니 궁금한 사람들은 확인해 보면 좋을 것이다.
이제 실제로 프로젝트에 등록해서 사용해 본다. 기본적인 파이어베이스 연동 과정은 생략한다.
먼저 프로젝트 gradle의 dependencies 블럭에 한 줄을 추가한다.
classpath 'com.google.firebase:perf-plugin:1.4.2'
그리고 앱 gradle의 최상단에 있는 plugins 블럭과 의존성에 각각 Performance SDK를 추가한다. bom이라는 의존성을 추가할 경우 그 밑에 있는 의존성의 버전은 지정할 필요가 없다.
plugins {
id 'com.google.firebase.firebase-perf'
}
.
.
.
implementation(platform("com.google.firebase:firebase-bom:32.1.1"))
implementation("com.google.firebase:firebase-perf-ktx")
매니페스트에도 Performance를 사용할 수 있게 meta-data 태그를 추가한다.
<meta-data
android:name="firebase_performance_logcat_enabled"
android:value="true" />
그리고 XML에 Performance 라이브러리를 호출할 수 있게 대충 버튼 하나 놓는다. 이후 액티비티 코드를 작성한다. 아래는 간단한 예시 코드다.
import android.os.Bundle
import com.example.kotlinprac.BaseActivity
import com.example.kotlinprac.R
import com.example.kotlinprac.databinding.ActivityFirebasePerformanceBinding
import com.google.firebase.ktx.Firebase
import com.google.firebase.perf.ktx.performance
import com.google.firebase.perf.metrics.Trace
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import timber.log.Timber
class FirebasePerformanceActivity :
BaseActivity<ActivityFirebasePerformanceBinding>(R.layout.activity_firebase_performance) {
private lateinit var trace: Trace
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
bind {
btnPerformance.setOnClickListener {
trace = Firebase.performance.newTrace("trace start")
trace.start()
trace.incrementMetric("test_metric_name", 1)
trace.incrementMetric("second_test_metric_name", 1)
CoroutineScope(Dispatchers.IO).launch {
delay(3000L)
Timber.e("## 3초 대기 끝!")
trace.stop()
Timber.e("## Trace 완료")
}
}
}
}
}
로그 라이브러리로 Timber를 사용하는데 만약 없다면 Log 클래스로 바꾸고 함수의 1번 인자인 TAG 값만 추가해주면 컴파일 에러는 사라질 것이다.
복붙하지 않고 직접 코드를 치겠다면 Trace 클래스를 import할 때 주의한다. 같은 이름이지만 다른 패키지에 속하는 Trace 클래스들이 2개 있다. 잘못 import해서 컴파일 에러가 발생할 수 있으니 한 번 확인하고 import한다.
실행한 다음 파이어베이스 콘솔로 들어간다. 그리고 콘솔 왼쪽 탭의 출시 및 모니터링 > Performance를 클릭해서 Performance 대시보드로 이동한다.
그러면 아래와 같은 화면이 표시될 것이다. 팝업 하나가 표시될텐데 필요없다면 닫는다.
만약 아래 화면이 표시되지 않더라도 좀 기다려 본다. 즉시 반영되지 않을 수도 있다.
처음 들어갔을 땐 화면 하단의 네트워크 요청 탭이 선택되어 있을 것이다. 그것의 바로 오른쪽에 있는 커스텀 Trace를 클릭해야 위 코드에서 설정한 커스텀 Trace를 확인할 수 있다.
trace start를 클릭하면 아래와 같은 화면이 나온다.
이쯤에서 다시 코드를 확인한다. 다 볼 필요는 없어서 버튼 클릭 리스너 부분의 코드만 가져왔다.
btnPerformance.setOnClickListener {
trace = Firebase.performance.newTrace("trace start")
trace.start()
trace.incrementMetric("test_metric_name", 1)
trace.incrementMetric("second_test_metric_name", 1)
CoroutineScope(Dispatchers.IO).launch {
delay(3000L)
Timber.e("## 3초 대기 끝!")
trace.stop()
Timber.e("## Trace 완료")
}
}
버튼을 클릭했을 때 newTrace() 안에 "trace start"라는 문자열을 넣었다. 이것이 내가 추적하고자 하는 Trace의 이름이다.
그리고 start()를 호출해 추적을 시작하게 한 다음, incrementMetric() 안에 2가지 문자열과 1을 각각 넣었다. 이것들은 Trace의 이름 우측에서 확인할 수 있다.
이후 코루틴을 통해 IO 쓰레드에서 3초 기다렸다가 stop()을 호출해 추적을 종료한다. 전체 로직은 매우 간단하지만 trace 참조를 통해 호출하는 함수들의 의미를 알아야 한다.
- newTrace() : 매개변수를 이름으로 하는 Trace 객체를 만드는 함수다. 매개변수로 넘기는 문자열은 문자열 앞뒤로 공백이 있으면 안되고, 문자열 앞에 언더바가 있거나 100글자를 넘기면 안 된다. 예를 들어 " test "나 "_test"같은 문자열은 사용하지 않는 걸 권장하고 있다.
실제로 문자열 앞에 언더바를 붙인 형태로 매개변수를 설정한 뒤, 앱을 재실행해서 버튼을 클릭하면 로그캣에 error 레벨의 로그가 표시된다.
trace.incrementMetric("_test_metric_name", 1)
Cannot increment metric '_test_metric_name'. Metric name is invalid.(Metric name must not start with '_')
문자열의 앞뒤로 공백이 있는 경우에는 실행도 되고 대시보드에 해당 항목이 표시되긴 한다. 그러나 하지 말라는 걸 굳이 할 필요가 없다.
trace.incrementMetric(" aaabbb ", 2)
- incrementMetric(metricName: String, incrementBy: Long) : 1번 매개변수를 이름으로 갖는 항목을 2번 매개변수만큼 증가시킨다. 이 때 해당 이름의 metric이 없다면 새로 생성된다. start()를 아직 호출하지 않은 상태거나 stop()을 호출한 후 해당 함수를 호출하면 아무 일도 일어나지 않는다.
실제로 코드를 수정해서 start() 함수를 incrementMetric() 뒤로 옮겨 본다.
btnPerformance.setOnClickListener {
trace = Firebase.performance.newTrace("trace start")
// trace.start()
trace.incrementMetric("test_metric_name", 2)
trace.incrementMetric("second_test_metric_name", 2)
trace.start()
CoroutineScope(Dispatchers.IO).launch {
delay(3000L)
Timber.e("## 3초 대기 끝!")
trace.stop()
Timber.e("## Trace 완료")
}
}
}
이후 앱을 실행해서 버튼을 클릭하면 로그캣에 아래 로그가 표시된다. 대충 추적이 시작되지 않아서 2가지 항목의 숫자값들을 증가시킬 수 없단 뜻이다.
대시보드에도 유의미한 변화는 보이지 않는다. 아마 stop() 뒤에 incrementMetric()을 호출하게 바꿔도 결과는 비슷할 것이다.
추가로 함수에 특정 어노테이션을 추가하면 해당 함수의 시작 부분에서 trace가 시작되고, 함수 안의 모든 로직들이 종료된 후에 trace가 중지된다. 아래 코드를 참고한다.
import android.os.Bundle
import com.example.kotlinprac.BaseActivity
import com.example.kotlinprac.R
import com.example.kotlinprac.databinding.ActivityFirebasePerformanceBinding
import com.google.firebase.ktx.Firebase
import com.google.firebase.perf.ktx.performance
import com.google.firebase.perf.metrics.AddTrace
import com.google.firebase.perf.metrics.Trace
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import timber.log.Timber
class FirebasePerformanceActivity :
BaseActivity<ActivityFirebasePerformanceBinding>(R.layout.activity_firebase_performance) {
private lateinit var trace: Trace
@AddTrace(name = "onCreateTest")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
bind {
btnPerformance.setOnClickListener {
trace = Firebase.performance.newTrace("trace start")
trace.start()
trace.incrementMetric("test_metric_name", 2)
trace.incrementMetric("second_test_metric_name", 2)
CoroutineScope(Dispatchers.IO).launch {
delay(3000L)
Timber.e("## 3초 대기 끝!")
trace.stop()
Timber.e("## Trace 완료")
}
}
}
}
}
onCreate() 위에 @AddTrace 어노테이션이 붙었다. 이 어노테이션은 앞서 말한대로 함수에 적용할 경우 주어진 이름으로 Trace 객체를 만들고 추적 시작, 중지가 자동으로 수행된다. 원래 2번 인자도 있지만 기본값이 true고 공식문서 예제에서도 true 값을 명시적으로 선언해두기 때문에 굳이 쓸 이유가 없어 보여서 쓰지 않았다.
어노테이션 추가 후 앱을 실행해서 버튼을 클릭하고 잠시 후 대시보드를 확인하면 onCreateTest라는 항목이 새로 생긴 걸 볼 수 있다.
onCreate()에서 서버 통신 등 별다른 로직이 없기 때문에 클릭해도 별 유의미한 데이터는 보이지 않는다. 하지만 어노테이션을 추가한 후에 새 항목이 생겼다는 것이 중요하다.
이제 이걸 바탕으로 공식문서의 다른 부분들도 읽어보고 다른 사람들의 글도 확인하면서 앱 성능을 개선시키면 되겠다.
참고한 사이트)
https://firebase.google.com/docs/reference/kotlin/com/google/firebase/perf/FirebasePerformance
'Android' 카테고리의 다른 글
[Android] 반응형 프로그래밍(Reactive Programming)이란? RxKotlin + MVVM + Hilt 예시 (0) | 2023.07.26 |
---|---|
[Android Compose] LaunchedEffect란? (0) | 2023.07.14 |
[Android] JUnit4 환경에서 단위 테스트 작성하는 법 (Github API) (0) | 2023.07.02 |
[Android] 코루틴 채널(Channel)이란? (0) | 2023.06.29 |
[Android] Parcelize란? (0) | 2023.06.21 |