Compose 성능 개선 isLinkBufferComposerEnabled

MSU·2026년 6월 9일

Android

목록 보기
37/42

ComposeRuntimeFlags.isLinkBufferComposerEnabled는 Jetpack Compose 내부에서 UI 트리를 관리하는 데이터 구조인 SlotTable의 아키텍처를 혁신적으로 변경하는 실험적(Experimental) 기능 플래그입니다.

기존의 메모리 관리 방식인 GapBuffer 대신 새로운 LinkBuffer 구조를 사용하도록 활성화하는 역할을 합니다.

1. 등장 배경: SlotTable과 GapBuffer의 한계

Jetpack Compose는 모든 컴포저블의 상태, ID, 트리 구조 정보를 SlotTable이라는 내부 데이터 구조에 저장합니다. Compose 출시 초기부터 지금까지 이 SlotTable은 Gap Buffer(갭 버퍼) 구조를 기반으로 작동해 왔습니다.

  • Gap Buffer 방식: 데이터를 하나의 연속된 평면 배열(Flat Array)에 저장하고, 데이터의 삽입/삭제가 일어나는 지점에 'Gap(빈 공간)'을 두어 이동시키는 방식입니다.
  • 문제점 (List Reordering의 한계): Column이나 Row 내에서 아이템의 순서가 바뀔 때(드래그 앤 드롭, 정렬 변경 등), Gap Buffer는 새로운 위치로 데이터들을 옮기기 위해 배열 내부의 요소들을 대량으로 복사(Array Copying)해야 했습니다. 이 때문에 리스트가 길어질수록 순서 변경 시 연산 비용이 급격히 증가(O(N)O(N))하는 성능 병목이 있었습니다.

2. LinkBuffer의 도입과 원리

isLinkBufferComposerEnabled = true를 설정하면, 이 평면 배열 구조가 연결 리스트(Linked List) 형태의 LinkBuffer 구조로 대체됩니다.

  • 포인터 기반 연결: 그룹(Group) 데이터 자체는 메모리 효율성을 위해 여전히 IntArray에 저장되지만, 각 그룹은 부모, 자식, 형제 노드들과 명시적인 포인터(필드)로 연결됩니다.
  • 주요 변화: * 리스트의 순서를 바꿀 때 데이터를 실제로 복사해서 이동시키는 것이 아니라, 포인터(링크)의 연결만 새로 고쳐주면 됩니다.
    • 결과적으로 구조적 변경 연산의 시간 복잡도가 O(1)O(1)에 가깝게 줄어듭니다.

3. 성능 향상 효과

이 플래그를 활성화했을 때 가장 드라마틱한 성능 향상이 일어나는 구간은 다음과 같습니다.

  • 리스트 아이템 재정렬 (List Reordering): 벤치마크 결과, 아이템 순서 변경 연산 속도가 2배 이상(100% 이상) 빨라집니다.
  • 조건부 콘텐츠 & MovableContent: 특정 조건에 따라 UI 레이아웃의 구조가 통째로 바뀌거나, MovableContent를 통해 UI 노드가 다른 부모 밑으로 이동할 때 발생하는 오버헤드가 제거됩니다.
  • 일반적인 UI 업데이트: 구조적 변경이 없는 일반적인 스크롤이나 단순 수치 변경(LazyColumn의 단순 스크롤 등) 상황에서도 전반적으로 약 10% 내외의 성능 향상을 보여줍니다.

4. 사용 방법 및 주의사항

setContent { ... }가 호출되기 전(예: Application 클래스의 onCreate 등)에 플래그를 설정해야 합니다.

import androidx.compose.runtime.ComposeRuntimeFlags

class MyApplication : Application() {
    override fun onCreate() {
        super.onCreate()
        
        // LinkBuffer 활성화
        ComposeRuntimeFlags.isLinkBufferComposerEnabled = true
    }
}

isLinkBufferComposerEnabled는 Jetpack Compose의 내부 런타임 클래스 구조와 필드를 직접 변경하고 접근하는 기능이므로 릴리즈 빌드 시 코드 난독화 및 최적화 도구인 R8(ProGuard)이 이 내부 플래그나 관련 클래스를 마음대로 지우거나 이름을 바꾸지 못하도록 프로가드 규칙(proguard-rules.pro)에 유지(Keep) 명령을 명시적으로 추가해 주어야 합니다.

규칙을 추가하지 않으면 릴리즈 빌드 앱이 구동되자마자 크래시(ClassNotFoundException 또는 NoSuchFieldError 등)가 발생할 수 있습니다.

# Jetpack Compose LinkBuffer 활성화를 위한 R8/ProGuard 규칙
-keep class androidx.compose.runtime.ComposeRuntimeFlags { *; }
-keep class androidx.compose.runtime.internal.** { *; }

# (선택) 만약 에러가 지속된다면 연관된 SlotTable 관련 내부 구조도 유지합니다.
-keep class androidx.compose.runtime.SlotTable { *; }
-keep class androidx.compose.runtime.Anchor { *; }
profile
안드로이드공부

0개의 댓글