Android/Android Compose

Android Compose 의 @Immutable 와 @Stable

최데브 2024. 8. 20. 21:11

Jetpack Compose에서 @Immutable와 @Stable 어노테이션은 컴포저블 함수의 리컴포지션을 최적화하는 데 중요한 역할을 합니다. 각각의 어노테이션은 특정한 상황에서 사용되며, 사용하는 것과 사용하지 않는 것에 따라 성능에 미치는 영향이 달라집니다.

1. @Immutable

@Immutable 어노테이션은 클래스가 불변(immutable)임을 명시합니다. 불변 객체는 상태가 변경되지 않기 때문에, Jetpack Compose는 해당 객체가 변경되지 않는다고 가정하고 리컴포지션을 피할 수 있습니다.

언제 사용할까?

@Immutable은 객체가 불변이며, 내부의 모든 필드도 불변 객체일 때 사용합니다. 이는 데이터 클래스와 같은 경우에 자주 사용됩니다.

예시:

@Immutable 
data class User(val name: String, val age: Int)
 

이 경우 User 클래스는 @Immutable로 표시되었기 때문에, Jetpack Compose는 이 객체가 변경되지 않는다고 가정하고, 이 객체를 사용하는 컴포저블 함수는 불필요한 리컴포지션을 피할 수 있습니다.

사용하지 않았을 때:

만약 @Immutable을 사용하지 않고 User 객체를 전달한다면, Jetpack Compose는 이 객체가 변경될 수 있다고 가정하고, 객체가 전달될 때마다 리컴포지션이 발생할 수 있습니다.

2. @Stable

@Stable 어노테이션은 객체가 안정적(stable)임을 명시합니다. 이 말은 객체의 특정 프로퍼티가 변경될 수 있지만, 객체 자체는 변경되지 않거나 자주 변경되지 않는다는 것을 의미합니다. 객체가 안정적이기 때문에, Jetpack Compose는 이 객체가 자주 변경되지 않는다고 가정하고 불필요한 리컴포지션을 피하려고 시도합니다.

언제 사용할까?

@Stable은 객체의 특정 프로퍼티가 변경될 수 있지만, 객체 자체는 변경되지 않거나 자주 변경되지 않는 경우에 사용합니다. 예를 들어, 뷰 모델과 같은 클래스에 적용할 수 있습니다.

예시:

@Stable 
class Counter(var count: Int)

 

이 경우 Counter 클래스는 @Stable로 표시되었기 때문에, count 속성이 변경되더라도 Jetpack Compose는 이 객체가 자주 변경되지 않는다고 가정하고 불필요한 리컴포지션을 피하려고 합니다.

사용하지 않았을 때:

만약 @Stable을 사용하지 않고 Counter 객체를 전달한다면, Jetpack Compose는 이 객체가 불안정하다고 가정하고, 객체의 속성이 변경될 때마다 리컴포지션을 발생시킬 수 있습니다.

 

+ Stable 의 설명이 조금 모호한게 있습니다. '자주 변경되지 않는다고 가정하고 불필요한 리컴포지션을 피하려고 한다. ' 라는 말의 설명을 덧붙이겠습니다.

 

@Stable 어노테이션이 의미하는 것은, 객체 자체가 자주 변경되지 않으며, 객체의 상태가 변경될 가능성이 있지만 그 변경이 객체 전체에 영향을 주지는 않는다는 것입니다. 좀 더 구체적으로 설명하자면

 

@Stable 객체는 내부의 특정 속성값이 변할 수 있습니다. 하지만 Jetpack Compose는 이 객체 자체가 자주 변하지 않는다고 가정합니다. 그래서 컴포저블이 이 객체를 사용할 때, 모든 속성의 변화를 계속 감시하고 그때마다 리컴포지션을 일으키는 대신, 안정적(stable)이라고 판단한 객체의 변화만 신경 써서 필요할 때만 리컴포지션을 발생시키는 것입니다.

 

예를 들어, Counter라는 클래스가 있다고 가정해 보겠습니다. 이 클래스는 count라는 변할 수 있는 속성을 가지고 있습니다. 하지만 클래스 자체는 자주 새로 만들어지지 않을 거라고 가정할 수 있습니다. 이럴 때 @Stable을 붙이면, count가 변하더라도 Jetpack Compose는 "이 클래스는 큰 변화가 없다"라고 가정하고, 모든 속성을 다 검사하지 않고 필요한 부분만 리컴포지션을 발생시킵니다.

즉, @Stable을 붙이면 객체의 변화가 리컴포지션을 최소한으로 발생시키도록 도와주고, 그로 인해 성능 최적화가 이루어질 수 있습니다.

이 어노테이션을 사용하지 않으면, Compose는 이 객체가 불안정하다고 판단하여 작은 변화에도 컴포저블이 전체적으로 다시 그려질 가능성이 커지게 됩니다.

요약

  • @Immutable: 객체가 불변일 때 사용합니다. 이 어노테이션을 사용하면 Jetpack Compose는 해당 객체를 사용하는 컴포저블이 리컴포지션되지 않도록 최적화합니다.
  • @Stable: 객체가 불변은 아니지만 안정적일 때 사용합니다. 이 어노테이션을 사용하면 Jetpack Compose는 해당 객체를 자주 변경되지 않는다고 가정하고 리컴포지션을 줄이려 합니다.

이 두 어노테이션을 적절히 사용하면 컴포저블 함수의 불필요한 리컴포지션을 줄여 성능을 최적화할 수 있습니다. 반대로, 사용하지 않으면 Jetpack Compose가 객체의 변경 여부를 더 자주 검사하게 되어, 리컴포지션이 자주 발생할 수 있습니다.

반응형