안녕하세요 점냥입니다 :)
빌드 속도는 평소 신경 쓰고 개발하지는 않았어요. 그런데 최근 회사에서 CI/CD에 관심을 가져 Github Action으로 테스트를 해보고 있었는데, 1주 조금 지나서 무료 플랜에 제공되는 가상 머신 빌드 시간을 다 써버렸지 뭐예요. 곧바로 유료 플랜으로 결제를 시도했고 잘 사용하고 있지만, Github Action의 과금 기준이 빌드 시간이 되어 버리면서 빌드 속도를 개선에 대해서 관심을 가지게 되었어요.
여러분의 Android 프로젝트 빌드는 얼마나 걸리나요?
회사 프로젝트를 돌리면 대략 5분 정도 걸리고 주변 Android 개발자에게 주워듣기로는 오래 걸리면 30분, 적게 걸리면 5분 이내로 다양하더군요. 빌드 시간에 대한 객관적인 지표가 없다 보니 5분이라는 시간이 빠른 건지, 느린 건지 잘 모르겠어요. 그래도 빌드 속도를 개선할 수 있는 방법에 대해 알아보고 정리해보려고 합니다!
그런데 빌드 속도는 Android Studio IDE, Gradle version, CPU 성능 등 아주 다양한 환경적 요인에 의해서 달라질 수 있어요. 이후 소개해드릴 방법들은 여러분 프로젝트 빌드 속도에 좋은 영향을 줄 수도 있고, 미미한 영향을 줄 수도 있어 참고해서 봐주시면 감사하겠습니다.
빌드 속도 측정
빌드 속도 개선이라는 주제로 블로그 글을 쓴다고 했을 때 그냥 방법들만 글로 나열하는 것은 하고 싶지 않았어요. 그러다가 2017 Google IO - speed up android라는 주제로 발표된 영상 속에서 이전 빌드 속도와 개선된 빌드 속도를 비교해주는 방법이 집중도 잘되고 흥미롭다고 생각이 들었습니다. 그래서 이번 글에 해당 영상을 참고해서 동아리 앱의 실제 빌드 속도를 비교해보면서 소개해보려고 합니다 (두근두근)
gradlew clean build --profile
빌드 속도를 측정 방법도 다양하지만 저는 Gradle Command를 사용해서 빌드 시간을 측정했어요.
이번 기회에 Gradle 관련에서 찾아보다 보니 빌드에 대해서도 여러 명령어와 옵션이 있다는 것을 알게 되었어요. Gradle 명령어로 빌드를 진행할 때 --profile 옵션을 주게 되면 보고서를 받을 수 있어요! 여러분도 이 글을 읽고 나서 빌드 개선을 위해 시간을 측정할 때 참고해보세요!
MashUp 프로젝트 빌드 시간은?
아쉽게도 개인 블로그에 올라가는 글이기 때문에 회사 프로젝트가 아닌 동아리에서 현재 개발 중인 프로젝틀 가지고 빌드 속도 개선하는 작업을 진행하려고 해요. 측정하려는 빌드 속도는 3가지입니다.
Full Build
Full Build는 clean build로 측정되는 시간을 의미해요. clean을 통해 빌드 속도 개선해주는 여러 요소들을 완전히 제거한 뒤에 아무것도 없는 상태로 빌드 속도를 측정합니다. 명령어는 gradlew clean build로 할 수 있어요
Incremental Build(증분 빌드)
Incremental Build는 Full Build와 다르게 이전 빌드에서 수행한 Task의 입력과 출력을 이용하여 입력이 동일하다면 이전 출력 값을 재활용해서 빌드 속도를 개선해요. 사진처럼 재활용하여 Task를 수행하지 않고 넘어간 경우, 작업에 대한 결과로 up-to-date 문자열이 출력되는 것을 확인할 수 있어요!
그리고 증분 빌드는 평소에 개발하면서 자주 수행하는 빌드로 오히려 Full Build보다 자주 수행하기 때문에 빌드 속도 개선에 의의가 있어요. 그래서 함수 또는 클래스를 추가하거나 삭제하고 측정한 빌드 시간, 이미지와 xml 파일을 추가하거나 삭제하는 작업을 한 후 측정한 빌드 시간을 개선해볼 거예요.
Tip 1. Gradle 빌드 옵션 추가하기
org.gradle.caching=true
org.gradle.parallel=true
Android 프로젝트 파일 중에 gradle.properties 파일은 Gradle의 속성을 선언하는 파일이에요. 이곳에 Gradle 옵션을 추가하여 빌드 속도를 개선해볼 수 있어요.
org.gradle.caching
Gradle 캐싱은 이전 빌드의 입력과 출력을 캐싱하여 이 값을 재활용해서 빌드 속도를 개선하는 방법이에요. 어라? 이미 앞서 소개한 증분 빌드와 동일한 기능처럼 보이네요. 하지만 달라요! 증분 빌드는 값을 바로 이전 빌드에 대해서만 재활용할 수 있어 Branch를 옮겨 재 빌드한 경우 재활용하지 못하고 다시 수행하는 모습을 볼 수 있어요.
Gradle 캐싱은 로컬에 캐싱할 수도 있고 CI를 원격 서버에 구현한 경우, 다른 사람이 저장한 Gradle 작업을 재활용할 수도 있다고 하네요
org.gradle.parallel
parallel은 Gradle의 project, Android에서는 module을 병렬적으로 빌드하는 옵션이에요. 따라서 멀티 모듈 구조로 Android 프로젝트를 개발하고 있는 경우에만 효과가 있어요.
Tip 2. Jetifier flag 지워보기
android.enableJetifier=false // 혹은 지우기
Jetifier는 타사 라이브러리에서는 아직 support 라이브러리를 쓰고 있다면 컴파일 타임일 때 AndroidX 라이브러리로 변환해주는 라이브러리에요. 이렇게 설명을 들으면 필요한 옵션처럼 보일 수 있어요. 하지만 요즘은 대부분 라이브러리들이 AndroidX로 마이그레이션을 완료했기 때문에 빌드 타임 때 support 라이브러리를 사용하고 있는지 확인하는 작업이 불필요할 수 있어요.
Jetifier 지워도 되는지 체크하기
Android IDE에서 제공해주는 Build Analyzer는 Jetifier를 사용해야 하는 건지 선언한 의존성을 분석해서 체크해줘요.
MashUp Android 앱은 제거해도 되는지 테스트해볼까요? ฅʕ•ㅅ•ʔฅ
빌드 시간이 오히려 늘어난 것 처럼 보이지만 몇 초 차이는 크게 영향이 없다고 해요. 실제로 빌드할 때마다 빌드 시간의 오차가 5초 정도 있어서 효과가 미미했다라고 보는 것이 좋아 보이네요..!
Tip 3. 비 전이적 R 클래스 사용하기
android.nonTransitiveRClass=true
다중 모듈일 경우 고려해보면 좋은 기능이에요. Android Module은 resource를 담은 자체적인 R class를 생성하는데 기본적으로 참조하고 있는 모듈의 resource도 포함해서 생성이 돼요. 이것은 다중 모듈에 참조가 복잡한 경우 비효율적인 구조일 수도 있고 리소스 중복되는 문제도 해결해준다고 해요.
문제점
private fun setUi() {
setStatusBarColorRes(com.mashup.core.common.R.color.brand500)
...
}
override val layoutId: Int = R.layout.activity_splash
그런데 한 클래스 파일에서 서로 다른 모듈의 resource 접근이 필요한 경우 위처럼 package를 명시해줘야 하는 이슈가 있어요. kotlin의 alias...? 이것으로 할 수 있는 것인지 그런데 번거로운 작업이라 애매하네요. 좋은 방법 있으면 알려주세요!
마무리
Full Build | Incremental Build - kotlin | Incremental Build - resource | |
초기 | 123 | 63 | 72 |
개선 후 | 74 | 61 | 84 |
결과를 보면 Full Build의 시간은 45% 정도 개선이 되었지만 Incremental Build의 속도는 미미하거나 오히려 늘어나기도 했네요. ㅎㅎ 그런데 빌드 측정하는 과정에서도 매번 시간이 달라지더라고요.. 그래서 참고만 해주시면 좋을 것 같아요.
관련 자료를 찾아보니까 아직 이 글에서 다루지 못한 여러 빌드 개선 방법이 있는 것 같아요. 관심 있는 분들을 위해 참고 자료 많이 남겨놓을게요!
참고
- https://developer.android.com/studio/build/optimize-your-build
- Pluu Dev - [요약] 최신 안드로이드 Gradle 플러그인으로 빌드를 더 빠르고 강력하게 만드십시오 (Android Dev Summit '21)
- https://docs.gradle.org/current/userguide/performance.html
'Android > Gradle' 카테고리의 다른 글
[Android] Gradle 버전 카탈로그를 사용해 버전 관리하기 (0) | 2023.06.01 |
---|---|
[Android] Spotless 설정으로 팀과 코드 컨벤션 맞추기 (3) | 2022.10.03 |
[Android] RepositoriesMode (0) | 2022.09.03 |