公開日: 2024/02/29
ComposeのStabilityはComposableのRecomposeによるパフォーマンス低下を改善するための重要な概念の一つです。
しかしながら少し複雑で理解しにくい部分があるため本記事でStabilityについてわかりやすく解説します。
結論から説明するとStabilityとは「不要なRecompositionをスキップして効率的にUIを更新するための概念」のことです。
この意味が少しわかりづらいと思うので順を追って説明していきます。
RecompositionとはComposable関数のパラメータが変更されたときに、Composable関数を再実行することです。
例えば、以下のようなComposable関数があるとします。
(Android Developersの説明わかりやすいので引用して説明します)
@Composable
fun LoginScreen(showError: Boolean) {
if (showError) {
LoginError()
}
LoginInput()
}
@Composable
fun LoginInput() { /* ... */ }
@Composable
fun LoginError() { /* ... */ }
Composable関数LoginScreen
のshowError
パラメータが変更されるとRecompositionが発生し、下図のようにCompositionツリーが更新されます。
Recompositionが発生してCompositionツリーが更新されている様子
また効率的にUIを更新するために、以下2つの条件を満たしたComposable関数はRecompositionをスキップすることができます。
stable
である条件の詳細を順番に解説します。
これは全てのパラメータをObject.equals()
で比較することで判断をします。
例えば、initialUiState
とupdatedUiState
はメモリの参照先は違いますが同じtext
の文字列hoge
を持っているので、Object.equals()
はtrue
となります。
data class UiState(
val text: String
)
val initialUiState = UiState(
text = "hoge"
)
val updatedUiState = UiState(
text = "hoge"
)
initialUiState.equals(updatedUiState) // => true
initialUiState === updatedUiState // => false
stable
であるここで登場するのがStabilityの概念です。
Composable関数のパラメータはstable
かunstable
に分類されます。
下記の2つのどちらかを満たすパラメータをstable
と言います。(満たさないパラメータをunstable
と言います)
型がimmutableであるとは、インスタンス生成したあと公開されているプロパティの値を変更できないことを表します。つまりインスタンスのプロパティを変更したい場合は新しくインスタンスを作り直す必要があります。
Boolean
,Float
,Int
などのプリミティブ型やString
についてもimmutableな型となります。
以下のクラスもimmutableとなります。
data class Post(
val id: Int,
val title: String,
val description: String,
)
すべてのプロパティはvalで定義されたプリミティブ型であり、Post
のプロパティの値を変更するには新しくインスタンスを作り直す必要があるからです。
以下のクラスはimmutableではありません。
data class Title(
var text: String
)
Title
クラスのプロパティtext
がvar
で定義されており、プロパティの値を変更が可能であるためです。
以下のようにMutableState、SnapshotStateMap、SnapshotStateListなどを使用したプロパティであればComposeランタイが値の変更を知ることができます。
例えばtext
の型はMutableState<String>
となり、text.value = "hoge"
のように記述することで値を変更できます。しかしながらこの値の変更をComposeランタイムに通知されるようになります。
data class Hoge(
val text by mutableStateOf("")
)
前述の通り、StabilityとはRecompositionと深いつながりがあり、不要なRecompositionをスキップして効率的にUIを更新するために用いられることがわかったかと思います。
参考になれば幸いです。
https://developer.android.com/jetpack/compose/performance/stability