grep

Engineering

[Jetpack Compose — Part 3] Jetpack Compose, 데이터로 성능과 안정성을 증명하다

야놀자

2025년 10월 24일

원문에서 보기 ↗

프로파일러 분석부터 원칙에 기반한 최적화까지, Compose에 대한 막연한 불안감을 기술적 확신으로 바꾸는 실전 최적화 가이드

이 이미지는 생성형 AI를 활용해 제작하였습니다.

이번 편은 Jetpack Compose 마이그레이션 시리즈의 마지막 파트입니다. Part 1, Part 2가 궁금하시다면 아래 링크를 확인해주세요.

1. [Jetpack Compose — Part 1] 낡은 캔버스에서 새 캔버스로:

Jetpack Compose와 함께한 마이그레이션 여정 Compose, 실전에서 빛을 발하다

낡은 캔버스에서 새 캔버스로: Jetpack Compose와 함께한 마이그레이션 여정

2. [Jetpack Compose — Part 2] Compose, 실전에서 빛을 발하다: 코드는 1/4로, 생산성은 4배로!

[Jetpack Compose — Part 2] Compose, 실전에서 빛을 발하다: 코드는 1/4로, 생산성은 4배로!

이 글은 Jetpack Compose를 도입한 후 마주할 수 있는 성능 문제를 데이터 기반으로 해결하는 과정을 다룹니다. 특히, CPU 프로파일러를 활용해 복잡한 UI의 스크롤 성능 저하 원인을 분석하고, 주요 병목 지점에서 획기적인 성능 개선을 이뤄낸 실전 최적화 방법을 공유합니다.

1. ‘그래서, 정말 괜찮은 거야?’: Compose에 대한 막연한 불안감

Jetpack Compose는 선언형 UI의 간결함과 높은 개발 생산성으로 많은 안드로이드 개발자에게 새로운 가능성을 열어주었습니다. 하지만 새로운 기술 도입에는 늘 약간의 불안감이 따릅니다. “그래서, 정말 안정적인가? 기존 View 시스템보다 항상 좋은 선택일까?” 하는 근본적인 질문이죠.

특히 Compose를 처음 도입하는 팀이라면, 버전 안정화나 팀 내 숙련도 부족 문제에 직면할 수 있습니다. 여러 자료를 통해 ‘리컴포지션(Recomposition)’이 성능에 치명적인 영향을 줄 수 있다는 사실을 알게 되면, ‘우리가 혹시 잘못 사용해서 앱을 더 느리게 만드는 건 아닐까?’ 하는 걱정이 들기도 합니다.

이러한 불확실성을 없애기 위한 가장 좋은 방법은 ‘감’이 아닌 ‘데이터’에 의존하고, 기술의 내부 동작 원리를 이해하는 것입니다. ‘ Jetpack Compose Internals**’**와 같은 자료를 통해 팀 내에서 주기적인 스터디를 진행하며 기술적 확신을 쌓는 것이 중요합니다.

특히 리컴포지션이 언제, 왜, 어떻게 일어나는지를 결정하는 핵심 열쇠인 상태 스냅샷 시스템(State Snapshot System)을 이해하는 것이 큰 도움이 됩니다. Compose가 State의 변화를 readObserver와 writeObserver로 감지하고, 불변의 상태 사본인 Snapshot을 통해 리컴포지션을 효율적으로 관리하는 내부 메커니즘을 이해하게 되면, 비로소 성능을 제어할 수 있다는 자신감을 얻을 수 있습니다.

2. 데이터로 길을 찾다: CPU 프로파일러를 활용한 병목 추적

이론 학습으로 자신감을 얻었다면, 다음은 실제 코드에 적용해볼 차례입니다. 검증 대상으로는 앱에서 가장 복잡하고 동적인 UI 중 하나를 선택하는 것이 좋습니다. 예를 들어, 동적인 콘텐츠(이미지, 비디오 등)가 포함된 리스트가 좋은 대상이 될 수 있습니다.

의심의 시작: “이 화면, 왜 버벅일까?”

앱의 핵심 화면에서 스크롤 경험은 매우 중요합니다. 하지만 동적 콘텐츠가 포함된 리스트를 스크롤할 때, 미세하지만 분명한 버벅임(Jank)이 느껴지는 경우가 있습니다. 심지어 콘텐츠가 준비되기 전에 화면이 잠시 깜빡이는 현상이 발생하기도 합니다. 새로운 기술을 적용했는데 이전보다 사용자 경험이 나빠진다면, 반드시 원인을 분석하고 해결해야 합니다.

범인 추적: 진실의 방으로 들어간 프로파일러

문제의 원인을 찾기 위해 Android Studio의 CPU 프로파일러는 가장 강력한 도구입니다. 프로파일러를 실행하고 문제가 되는 화면을 스크롤하면, ‘Janky frames’ 타임라인에서 성능 기준치(16ms)를 초과하는 빨간색 막대들을 발견할 수 있습니다. 바로 이 부분들이 사용자에게 버벅임을 유발하는 주범입니다.

출처: Android 공식 페이지

문제가 되는 프레임을 선택하고, 분석에 가장 용이한 ‘Bottom Up’ 뷰를 확인해보세요. ‘Bottom Up’ 뷰는 특정 시간 동안 가장 많은 CPU 시간을 소비한 메서드를 역순으로 보여주므로, 병목 지점을 찾는 데 매우 효과적입니다.

분석 결과, 주된 원인으로 다음과 같은 유형들이 지목될 수 있습니다.

이는 단순한 UI 렌더링 문제가 아니라, 네트워크, 비동기 처리, 리소스 로딩에 걸친 복합적인 문제임을 시사합니다.

해결의 실마리: 원칙을 코드로 옮기다

분석을 통해 찾은 근본 원인은 ‘하나의 상태 변경이 너무 많은 작업을 연쇄적으로 유발한다’는 점일 때가 많습니다. 예를 들어, 특정 UI의 활성화 상태를 나타내는 isActive와 같은 State 값이 변경될 때마다 불필요한 리컴포지션이 발생하고, 이는 곧 코루틴의 과도한 실행과 리소스 재로딩으로 이어져 메인 스레드를 막는 것입니다.

문제를 해결하기 위해 다음과 같은 Compose의 핵심 원칙들을 코드로 옮겨볼 수 있습니다.

1. 상태 관리 최적화: LaunchedEffect로 상태와 생명주기 동기화

isActive와 같은 상태의 잦은 변경으로 인한 부하를 해결하기 위해 LaunchedEffect를 사용할 수 있습니다. 이는 ‘상태(State)와 이벤트(Event) 분리’ 원칙을 실제로 적용하는 좋은 사례입니다. 즉, isActive라는 상태 는 UI를 그리는 데만 사용하고, 활성화/비활성화 같은 이벤트 처리는 LaunchedEffect를 통해 명확히 분리하여 불필요한 리컴포지션을 방지할 수 있습니다.

2. 로딩 최적화: remember로 무거운 작업은 한 번만

미디어 플레이어의 prepare()와 같은 비용이 큰 초기화 메서드가 반복적으로 호출되는 문제를 해결해야 합니다. 이는 ‘remember의 올바른 사용법’ 원칙을 따르는 과정입니다. 비용이 큰 연산 결과나 객체는 remember로 감싸 재사용성을 높여야 합니다. 이 규칙에 따라, 미디어 플레이어 인스턴스와 prepare() 호출 로직 전체를 remember 블록으로 감싸면 리컴포지션이 일어나도 해당 로직이 다시 실행되지 않아 반복적인 로딩을 원천적으로 차단할 수 있습니다.

3. 깜빡임 문제 해결: 부드러운 UI 전환

마지막으로, 사용자 경험을 해치는 ‘화면 깜빡임’ 문제를 해결할 수 있습니다. 콘텐츠를 보여주는 View의 초기 투명도(alpha)를 0f로 설정한 뒤, 리소스가 준비되면 애니메이션을 통해 부드럽게 나타나도록 변경하는 것입니다. 이 작은 변화로 사용자는 더 이상 거슬리는 깜빡임 없이 자연스러운 UI 전환을 경험하게 됩니다.

3. 데이터가 가져온 확신: 획기적인 성능 개선

목표는 단순히 ‘버벅임을 없애는 것’을 넘어, ‘Compose는 올바르게 사용하면 뛰어난 성능을 제공한다’는 명제를 데이터로 증명하는 것입니다. 최적화 이전과 이후, 동일한 시나리오에서 CPU 프로파일러를 다시 측정했을 때, Janky Frame이 사라지고 CPU 사용량이 안정화된 것을 확인할 수 있습니다.

이러한 최적화 과정은 다음과 같은 중요한 가치를 가져다줍니다.

4. 여정은 계속된다: 더 높은 완성도를 향하여

이번 최적화 과정에서 얻은 가장 큰 교훈은, 새로운 기술을 도입하는 것보다 팀의 원칙을 가지고 체계적으로 접근하는 것이 더 중요하다는 사실입니다. 내부 동작 원리에 대한 깊이 있는 이해, 팀원 모두가 동의하는 코딩 가이드, 그리고 데이터를 기반으로 한 성능 검증 프로세스가 없다면 Compose의 잠재력을 온전히 활용하기 어렵습니다.

이제 다음 목표는 앱의 UI를 100% Compose로 전환하여 일관된 개발 경험을 구축하고, 안정적인 품질을 지속적으로 보장하기 위해 Compose UI 테스트 자동화를 도입하는 것이 될 수 있습니다.

이 글이 Jetpack Compose 도입을 고민하거나, 성능 문제로 어려움을 겪는 다른 개발자분들께 작은 도움이 되었으면 합니다. 궁금한 점이나 더 나누고 싶은 이야기가 있다면 언제든지 의견을 남겨주세요.

누구나 마음 편히 놀 수 있는 세상을 함께 만들어갈 동료를 찾고 있어요 :)

지금 채용 중인 포지션 보러가기 >