- androidx.compose.material.LinearProgressIndicator(
- progress = 0.5f,
- )
- androidx.compose.material3.LinearProgressIndicator(
- progress = { 0.5f },
- )
そのため、progress を lambda にすることで Composition と Layout phase をスキップして Drawing phase だけやり直せばよくなり、その分パフォーマンスが良くなります。
(https://developer.android.com/develop/ui/compose/phases)
実際以下のコードを実行して Layout Inspector で recomposition の回数を見ると、M2 の方は recompositoin されていますが M3 の方は skip されています。
- Column(
- verticalArrangement = Arrangement.spacedBy(16.dp),
- modifier = Modifier.fillMaxSize().padding(16.dp),
- ) {
- var progress by remember { mutableFloatStateOf(0f) }
- androidx.compose.material3.Button(
- onClick = { progress = Random.nextFloat() },
- ) {
- Text("update progress")
- }
- androidx.compose.material.LinearProgressIndicator(
- progress = progress,
- modifier = Modifier.fillMaxWidth(),
- )
- androidx.compose.material3.LinearProgressIndicator(
- progress = { progress },
- modifier = Modifier.fillMaxWidth(),
- )
- }
M3 の LinearProgressIndicator を wrap するときは、wrap する component でも progress を lambda で取るように注意してください(より正確に言うと、lamda の中で state から読み出しを行うようにするということ)。そうしないと M3 の LinearProgressIndicator を使っていても recompose が走ります。
- Column(
- verticalArrangement = Arrangement.spacedBy(16.dp),
- modifier = Modifier.fillMaxSize().padding(16.dp),
- ) {
- var progress by remember { mutableFloatStateOf(0f) }
- androidx.compose.material3.Button(
- onClick = { progress = Random.nextFloat() },
- ) {
- Text("update progress")
- }
- LinearProgressIndicatorM2(progress)
- LinearProgressIndicatorM3_Bad(progress)
- LinearProgressIndicatorM3_Good({ progress })
- }
- @Composable
- private fun LinearProgressIndicatorM2(progress: Float) {
- androidx.compose.material.LinearProgressIndicator(
- progress = progress,
- modifier = Modifier.fillMaxWidth(),
- )
- }
- @Composable
- private fun LinearProgressIndicatorM3_Bad(progress: Float) {
- androidx.compose.material3.LinearProgressIndicator(
- progress = { progress },
- modifier = Modifier.fillMaxWidth(),
- )
- }
- @Composable
- private fun LinearProgressIndicatorM3_Good(progress: () -> Float) {
- androidx.compose.material3.LinearProgressIndicator(
- progress = progress,
- modifier = Modifier.fillMaxWidth(),
- )
- }
そうは言っても、階層のどこかで progress が読み出されていることもあるでしょう(Text Composable で progress の値を表示しているとか)。その場合は rememberUpdatedState を使うことで LinearProgressIndicator の recomposition を skip させることができます。
- @Composable
- private fun Wrap(progress: Float, onUpdate: () -> Unit) {
- val updatedProgress by rememberUpdatedState(progress)
- Column(
- verticalArrangement = Arrangement.spacedBy(16.dp),
- modifier = Modifier.fillMaxSize().padding(16.dp),
- ) {
- ...
- LinearProgressIndicatorM3_Good({ updatedProgress })
- }
- }
0 件のコメント:
コメントを投稿