第7回:再コンポーズを恐れなくていい理由

― Compose を壊すのは「再コンポーズ」ではなく「誤解」だった ―

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

はじめに

Jetpack Compose を使い始めた多くの人が、必ずこう言います。

  • 「再コンポーズが多すぎて不安」
  • 「無駄に再コンポーズされていないか心配」
  • 「ログを見ると何回も呼ばれている」
  • 「パフォーマンスが悪くなりそう」

そして次のような“防衛コード”が増え始めます。

remember { mutableStateOf(...) }
rememberUpdatedState(...)
derivedStateOf { ... }

結果どうなるか。

👉 コードは複雑になり、設計は壊れ、バグは増える

この記事では、

  • 再コンポーズとは何か
  • なぜ恐れる必要がないのか
  • 本当に気をつけるべきポイントは何か

失敗例 → 仕組み → 正しい考え方 の順で解説します。

再コンポーズは「異常」ではない

まず大前提から。

再コンポーズは正常動作です

Compose は、

  • State が変わったら
  • 必要な UI を
  • 必要な範囲だけ
  • 再計算する

という設計です。

  • 再コンポーズ = UI の再評価
  • 再描画ではない

ここを混同すると、すべてが不安に見えます。

よくある誤解①

「Composable が何度も呼ばれている = 重い」

ログを仕込んで、こう思ったことはありませんか?

@Composable
fun MyItem() {
    Log.d("Compose", "called")
}

→ スクロールするたびに大量ログ。

しかし実際には、

  • 関数が呼ばれる
  • UIツリーを再計算
  • 差分だけを反映

という流れです。

👉 View を毎回 inflate しているわけではありません

Compose が速い理由

Compose は内部で、

  • Slot Table
  • 再利用
  • スキップ判定

を行っています。

重要なのはここ👇

同じ入力 → 同じ出力 ならスキップできる

だから Compose は、

  • 小さな Composable
  • 明確な引数
  • 不変データ

が大好物です。

本当に危険なのは「再コンポーズ」ではない

❌ 危険な例①:再コンポーズ中に副作用

@Composable
fun Sample(count: Int) {
    println("count = $count")
}

これが何度も呼ばれるのは当たり前です。

しかし本当に危険なのは👇

@Composable
fun Sample(count: Int) {
    api.fetch() // ← これ
}

👉 再コンポーズのたびに API 呼び出し

問題は再コンポーズではなく、副作用の置き場所です。

よくある誤解②

「再コンポーズを減らす providing remember を増やす」

val text by remember { mutableStateOf(param) }

これ、やっていませんか?

何が起きるか

  • param が変わっても反映されない
  • UI が古いまま
  • バグの温床

👉 remember は最適化ではない

remember は
「その Composable のライフサイクルに紐づけたい状態」
のためのものです。

 

「最適化しすぎて壊れる」典型例

❌ derivedStateOf 乱用

val isEnabled by remember {
    derivedStateOf {
        state.a && state.b && state.c
    }
}
  • 本来不要
  • 可読性低下
  • バグ時に追いにくい

ほとんどの場合、こうで十分です。

val isEnabled = state.a && state.b && state.c

👉 Compose はこれを毎回計算しても速い

 

再コンポーズを「恐れなくていい」本当の理由

理由①

再コンポーズは差分適用

  • 全UI再生成ではない
  • 必要な部分だけ更新

理由②

計算コストは想像より遥かに小さい

  • if
  • when
  • data class copy
  • Boolean 判定

👉 これらは問題になりません。

理由③

人間の設計ミスの方が圧倒的に重い

  • 不必要な remember
  • 状態の二重管理
  • キャッシュの破綻

最適化より正しさが重要

 

再コンポーズで本当に気をつけるべきこと

✅ 気にするべき3点だけ

① 副作用を直接書かない

  • API
  • DB
  • Log
  • Navigation

→ LaunchedEffect / DisposableEffect

② 不変データを渡す

  • data class
  • List は再代入
items = items + newItem

③ 状態の責務を分ける

  • UI State
  • UI Event
  • 一時的 State

 

「再コンポーズが怖い人」の思考パターン

多くの場合、こうです。

  • View 時代の感覚が抜けていない
  • onDraw = 重い という刷り込み
  • invalidate 地獄のトラウマ

Compose は 別物 です。

 

正しいマインドセット

再コンポーズは「敵」ではない
設計を教えてくれる「通知」

  • 無限に起きる → 副作用の場所が悪い
  • 想定外 → 状態設計が悪い

👉 再コンポーズは 設計レビューのヒント です。

 

まとめ

  • 再コンポーズは正常動作
  • 恐れるべきものではない
  • 最適化しすぎる方が危険
  • 副作用と状態設計がすべて

Compose において重要なのは、

「いつ・なぜ・何が再評価されるか」を
設計で説明できること

それができていれば、再コンポーズは味方になります。

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