[android] compose 의 stability
https://developer.android.com/jetpack/compose/performance/stability
#
compose 는 type 을 stable, unstable 로 구분한다.
type 이 immutable 이면 stable 이고, 이는 recomposition 시 compose 가 값 변경이 있었는지를 알아챌 수 있다는 것이다.
type 이 unstable 하다는 것은, recomposition 시 compose 가 값 변경이 있었는지를 알 수 없다는 것이다. (돼왕 : 그래서 안정성을 위해 항상 recomposition)
#
stable parameter 는 recomposition 시 값이 변경되지 않았다면 recompose 를 skip 시킨다.
unstable parameter 는 recomposition 시 무조건 recompose 를 시킨다.
#
stablility 관련 function marking 에는 skippable 과 restartable 이 있다.
skippable 은 composable 이 skip 가능하다는 것을 compiler 가 마킹한 것이고, recomposition 시 argument 가 이전값과 동일하면 recomposition 을 skip 한다는 의미이다.
restartable 은 state 가 변경되었을 때 코드를 다시 탈 수 있음을 의미한다.
https://developer.android.com/jetpack/compose/performance/stability/diagnose
Layout Inspector
#
Recomposition, Skipped count 를 실시간으로 볼 수 있다.
Compose Compiler Reports
#
어떤 composable 함수들이 skippable 하고 아닌지를 볼 수 있다.
#
setup & run the task 는 상단 링크 참조
#
output 은 3가지 형태로 나옴
- classes.txt : module 내 class 의 stability
- composables.txt : module 내 restartable & skippable composables 정보
- composables.csv : csv version
#
composables.txt 샘플
restartable skippable scheme("[androidx.compose.ui.UiComposable]") fun SnackCollection(
stable snackCollection: SnackCollection
stable onSnackClick: Function1<Long, Unit>
stable modifier: Modifier? = @static Companion
stable index: Int = @static 0
stable highlight: Boolean = @static true
)
restartable scheme("[androidx.compose.ui.UiComposable]") fun HighlightedSnacks(
stable index: Int
unstable snacks: List
stable onSnackClick: Function1<Long, Unit>
stable modifier: Modifier? = @static Companion
)
...
#
restartable skippable stable 이 가장 이상적인 형태
#
classes.txt 샘플
unstable class Snack {
stable val id: Long
stable val name: String
stable val imageUrl: String
stable val price: Long
stable val tagline: String
unstable val tags: Set
<runtime stability> = Unstable
}
...
위 결과 대상이 되는 class 는..
data class Snack(
val id: Long,
val name: String,
val imageUrl: String,
val price: Long,
val tagline: String = "",
val tags: Set = emptySet()
)
...
https://developer.android.com/jetpack/compose/performance/stability/fix
#
unstable type 은 성능이슈를 야기할 수 있다.
type 을 immutable 또는 stable 로 만들면 좋다.
#
collection 은 기본적으로 unstable 하다고 본다.
이를 해결하기 위해 compose compiler 는 immutable collection 을 지원한다.
ImmutableCollection, ImmutableList, ImmutableSet 등이 그것이다.
#
Stable 또는 Immutable 로 annotate 하는 것도 효과가 있다.
이것들이 실제 내용과 다를 수는 있지만 (@Stable 이라고 마킹한다고 실제 내용이 stable 한건 아니라는 뜻)
따라서 무조건 남발하면 안되고, runtime 에 stable 함이 보장될 때 쓰는 것이 좋다.
#
Collection 의 경우 Stable wrapper 를 사용하여 stable 로 만드는 방법도 있다.
@Immutable
data class SnackCollection(
val snacks: List
)
끝