🤖 Compose

[Compose] 안정성 stability

콩드로이드 2025. 2. 9. 16:44

안정성에 관해서도 가장 중요한 키워드는 Smart Recomposition 같아요 

 

Smart Recomposition

- composition 함수에서 사용되는 데이터가 변경된 데이터의 함수만 재호출 즉 일부분의 ui만 업데이트 

- 성능 최적화 

 

이 때 compose는 필요한 recomposition임을 어떻게 구분할까 ?  -> paramater로 구분

 

크게 3가지로 나눠본다면 

 

Stable parameters 

- 변경 시 컴포지션에서 추적이 가능하기 때문에 smart recomposition이 가능 

- 즉, 변경 사항이 없다면 compose는 skip

 

Unstable parameters 

- 변경 시 컴포지션에서 추적이 불가 -> 데이터의 변경 사항의 유무와 관계 없이 무조건 Recomposition

- 퍼포먼스에 안 좋은 영향

 

Immutable parameters 

- 변경 불가

- compose에선 당연히 변경 사항이 없을 거라 생각해서 skip 

data class Contact(val name: String, val number: String)

@Composable
fun ContactRow(contact: Contact, modifier: Modifier = Modifier) {
   var selected by remember { mutableStateOf(false) }

   Row(modifier) {
      ContactDetails(contact)
      ToggleButton(selected, onToggled = { selected = !selected })
   }
}

- contact의 paramater는 val로 지정 : immutable 

- contactDetails는 recomposition에서 제외 (smart recomposition)

 

근데 만약, data class에서 val이 아니라 var로 선언된다면 

data class Contact(var name: String, var number: String)

@Composable
fun ContactRow(contact: Contact, modifier: Modifier = Modifier) {
   var selected by remember { mutableStateOf(false) }

   Row(modifier) {
      ContactDetails(contact)
      ToggleButton(selected, onToggled = { selected = !selected })
   }
}

 

mutable이기 때문에 contactDetail이 무조건 recomposition 된다  

 

 

Compose를 Smart하게 사용하려면 Immutable이나, stable paramater를 사용하는 것이 좋다 .. ! 

(all primitive types and string are  immutable )

 

 


compose compiler report로 확인해보기 (compose가 함수를 어떻게 판단하는지)

빌드 전 build.gradle에 아래와 같이 추가 

  android { ... }

  composeCompiler {
    reportsDestination = layout.buildDirectory.dir("compose_compiler")
    metricsDestination = layout.buildDirectory.dir("compose_compiler")
  }

 

싱크 후 빌드하면 프로젝트 경로/app/build/compose_compiler 폴더에 파일들이 생성되어있습니다 

 

이런 코드를 빌드하고 리포트를 생성했는데, <modulename>-composables.txt 파일을 확인하면 

@Composable
fun Greeting(name: String, modifier: Modifier = Modifier) {
    Text(
        text = "Hello $name!",
        modifier = modifier
    )
}

 

아래와 같이 생성되어 있습니다 

restartable skippable scheme("[androidx.compose.ui.UiComposable]") fun Greeting(
  stable name: String
  stable modifier: Modifier? = @static Companion
)

stable / unstable : 위에서 살펴봤던 개념과 동일합니다 

 

restartable 

- composable이 recomposition의 진입점 (어느 부분부터 recomposition이 가능한지)을 나타냅니다 

 

skippable 

composable이 recomposition일 때 값이 변경되지 않았다면 recomposition을 skip할 수 있음을 나타냅니다

composable 함수의 모든 매개변수가 안정해야지만 붙을 수 skippable이 붙게됩니다  

 

위의 예제를 아래와 같이 변경해본다면 

data class NotStable(
    var name: String
)

@Composable
fun Greeting(dto: NotStable, modifier: Modifier = Modifier) {
    Text(
        text = "Hello ${dto.name}!",
        modifier = modifier
    )
}

 

compiler report에서 skippable이 빠진 걸 알 수 있습니다 

restartable scheme("[androidx.compose.ui.UiComposable]") fun Greeting(
  unstable dto: NotStable
  stable modifier: Modifier? = @static Companion
)

 

'🤖 Compose' 카테고리의 다른 글

[Compose] Rendering  (0) 2025.01.31
[Compose] Compose의 LifeCycle  (0) 2025.01.27
[Compose] 단방향 데이터 흐름  (0) 2025.01.23
[Compose] Navigation  (0) 2025.01.22
[Compose] Theme  (0) 2025.01.22