【Claude Code 失敗談 #10】Composeの再描画が止まらなくなった話

社員ブログ

※Claude Codeを使用して記事を作成しています。

シリーズ:Claude Codeを使ったAndroidアプリ開発 失敗談

  • #10:Composeの再描画が止まらなくなった話(状態管理の誤り) ← 今回

はじめに

Jetpack ComposeはAndroid UIの現代的な書き方ですが、状態管理を誤ると無限に再描画が発生します。
Claude Codeが生成したコードでも、この問題は起きることがあります。

やらかしたこと

メモ一覧画面をスクロールすると、目に見えてカクつくようになりました。
Android Profilerで確認すると、コンポーザブル関数が毎フレーム再実行されている状態でした。

該当コードを見ると:

// Claude Codeが生成したコード(問題あり)
@Composable
fun MemoListScreen(viewModel: MemoListViewModel = hiltViewModel()) {
    val memos by viewModel.memos.collectAsState()

    LazyColumn {
        items(memos, key = { UUID.randomUUID().toString() }) { memo -> // ← 問題
            MemoItem(memo = memo)
        }
    }
}

key = { UUID.randomUUID().toString() } の部分が問題でした。
再描画のたびに新しいUUIDが生成されるため、Composeがすべてのアイテムを「新しいもの」と判断して毎回再描画していました。

どう直したか

メモ一覧でLazyColumnを使っていますが、
再描画が毎フレーム発生してパフォーマンスが悪い状態です。

keyに UUID.randomUUID() を使っているのが原因と思われます。
メモのIDを安定したkeyとして使うように修正してください。
また、他に不必要な再描画を引き起こしている箇所があれば
合わせて修正してください。

修正後:

items(memos, key = { memo -> memo.id }) { memo -> // 安定したkey
    MemoItem(memo = memo)
}

ComposeをClaude Codeで使う際の注意点

Composeの状態管理で特に気をつけるポイントを、確認用の指示としてまとめました。

実装したコンポーザブルに以下の問題がないか確認してください。

・LazyColumnのkeyに不安定な値(random等)を使っていないか
・rememberを使わずにオブジェクトをコンポーザブル内で生成していないか
・Stateを引数で渡すのではなく直接collectしていないか
・不必要にrecomposeが走るコードになっていないか

問題があれば修正してください。

まとめ

Composeは宣言的UIで直感的に書けますが、パフォーマンスの落とし穴が細かい場所に潜んでいます。Claude Codeに「パフォーマンスの観点でも確認して」と一言添えることで、このような問題を未然に防げます。

次回:【Claude Code 失敗談 #11】Claude Codeに任せすぎてコードの意味が全くわからなくなった話

タイトルとURLをコピーしました