Notice
Recent Posts
Recent Comments
«   2026/07   »
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 31
Tags
more
Archives
Today
Total
관리 메뉴

훌륭한 개발자가 되기 위하여

Jetpack Compose의 안정성(Stability) 본문

안드로이드

Jetpack Compose의 안정성(Stability)

jay20033 2025. 7. 27. 23:54

안정성(Stability)란?

클래스나 타입이 동일한 매개변수 입력값에 대해 일관된 결과를 생성하도록 보장하는 속성이다.

👉 안정된 클래스나 함수는 recomposition이 여러 번 발생해도 의도와 다르게 동작이 변경되지 않도록 보장한다.

 

❓ Compose에서 안정성이 중요한 이유

composable 컴파일러는 컴포저블 함수의 매개변수를 검사하고 stable 또는 unstable로 분류한다.

이 정보는 Compose Runtime이 매개변수의 입력값 변경에 따라 컴포저블 함수를 다시 랜더링할지 여부를 결정하는데 사용되므로 효율적으로 recomposition을 관리하여 앱 성능 향상에 기여를 한다.


✅ Stable 파라미터일 때 특징

  1. 참조가 같으면 변경되지 않았다고 판단
    즉, stable 객체가 들어오면 equals 체크를 생략하고 참조 비교(pointer compare)로 충분.
  2. 만약 stable 객체가 내부적으로 값 변화 가능하면
    → Compose runtime이 자체 추적(State object)을 이용해 변화 감지.

👉 Stable 객체는 "값이 바뀌었는지 Compose가 신뢰하고 판단할 수 있는 타입"이다.


 

✔️ Stable로 간주되는 대표적인 경우

  • String을 포함한 원시 타입이 읽기 전용인 val로 정의된 경우
    • Int, Float, Boolean, String 등
  • 값을 캡처하지 않는 람다 표현식
    • ex) (Int) -> String 과 같은 함수 타입
    • 외부 상태를 캡처하지 않는 람다는 동작이 예측 가능하므로 Stable
val lambdaFunc: (Int) -> String
  • 클래스, val 이거나 immutable하고 stable 한 public 속성을 가진 데이터 클래스
data class User(
    val id: Int,
    val name: String
)
  • 안정성 어노테이션이 명시적으로 붙어있는 클래스
    • @Stable
    • @Immutable

✔️ Unstable 간주되는 대표적인 경우

  • 인터페이스 및 추상 클래스
    • List, Map, Any와 같은 인터페이스는 컴파일 시점에 구현체의 종류를 보장할 수 없기 때문
  • 가변적인 프로퍼티를 가진 클래스
    • 하나 이상의 가변적이거나 본질적으로 불안정하다고 간주되는 타입의 public 프로퍼티를 단 하나라도 포함하는 클래스
data class UnstableUser(
    val id: Int,
    var name: String
)

 


🥸 Composable 함수 추론하기

성능을 최적화하기 위해 컴파일러는 컴포저블 함수를 Restartable, Skippable, Moveable, Replaceable과 같은 유형으로 분류한다.

 

Restartable

  • recomposition 프로세스의 기본 단위 ➡️ 매개변수 입력값 or 상태가 변경되면 compose 런타임은 UI를 업데이트 하기 위해 recomposition을 위해 함수를 재호출함
  • 대부분의 컴포저블 함수는 기본적으로 Restartable로 간주

Skippable

  • 스마트 recomposition에 의해 활성화된 특정 조건 하에서 recomposition 스킵할 수 있음 ➡️성능 향상에 중요
  • 컴포저블 함수는 restartable이면서 동시에 skippable일 수 있음 ➡️ 필요할 때 recomposition 수행할 수 있지만 특정 조건이 허용되면 건너뛸 수 있음

Smart Recomposition이란?

컴파일러에서 제공하는 안정성 정보를 기반으로 불필요한 업데이트를 선택적으로 건너뛰어 UI 성능과 응답성을 최적화하는 매커니즘이다.

 

동작 방식

  1. 새로운 매개변수 입력값이 컴포저블 함수에 전달될 때마다 Compose는 클래스의 equals() 매서드를 이용하여 이전 값과 비교한다.
  2. Stable 매개변수
    • 입력값 동일 ➡️ equals()가 true 반환 ➡️ recomposition Skip
    • 입력값 바뀜 ➡️ equals()가 false 반환 ➡️ recomposition 트리거함
  3. Unstable 매개변수
    • Compose는 입력값 변경 여부에 관계없이 항상 recomposition 트리거함

안정성 어노테이션

@Immutable

클래스 내의 모든 속성이 컴파일러에 의해 변경 불가능한 것으로 처리되도록 보장한다.

@Immutable
data class User(
    val id: Int,
    val items: List<String>
)

👉 List는 기본적으로 Unstable이지만 @Immutable 때문에 명시적으로 stable 유형으로 만들 수 있음

 

💥유의사항

  • 모든 필드가 val
  • 필드 타입도 모두 immutable

@Stable

속성이 immutable 하거나 recomposition에 영향을 미치지 않는 제어된 가변성을 가진 클래스에 사용

👉 읽기 전용보다는 강력하지만 @Immutable 어노테이션 보다는 덜 엄격함

👉 클래스 자체는 stable로 간주되지만 해당 속성은 여전히 변경될 수 있음

@Stable
class PlayerState {
    var position by mutableFloatStateOf(0f)
    var isPlaying by mutableStateOf(false)
}

@Immutable ⚔️ @Stable

구분 @Immutable @Stable
불변성 완전 불변 제어된 가변성
프로퍼티 모두 Immutable Mutable 허용
사용 사례 DTO, Model UI State
Recomposition 완전히 Skip 가능 상태 변경시 트리거

 

참고자료

https://developer.android.com/develop/ui/compose/performance/stability?hl=ko

https://velog.io/@skydoves/compose-stability

'안드로이드' 카테고리의 다른 글

[Jetpack Compose] State Hoisting이란?  (0) 2025.08.09
[Jetpack Compose] State와 Remember란?  (0) 2025.08.06
Jetpack Compose의 동작 구조  (0) 2025.07.26
네트워크 상태 읽기  (0) 2025.02.20
Jetpack Compose Stability  (1) 2025.01.20