Compose の安定性

Compose は、型を安定版か不安定版かと見なします。型が不変の場合 不変であるか、あるいはその値が変化したかどうかを Compose が 再コンポーズ時に変化が生じますCompose が型を判別できない場合、型は不安定になります。 その値が再コンポーズ間で変化した場合です。

Compose は、コンポーザブルのパラメータの安定性を使用して、 次のように、再コンポーズ中にコンポーザブルをスキップできます。

  • Stable パラメータ:コンポーザブルに、 Compose はスキップします。
  • 不安定なパラメータ: コンポーザブルに不安定なパラメータがある場合、Compose は コンポーネントの親を再コンポーズするときは必ず再コンポーズします。

Compose が常に想定する不必要に不安定なコンポーネントがアプリに含まれている場合 再コンポーズを行うと、パフォーマンスの問題やその他の問題が発生する可能性があります。

このドキュメントでは、アプリの安定性を高めて 全体的なユーザーエクスペリエンスが向上します

不変オブジェクト

次のスニペットは、安定性とレイテンシの背後にある一般原則を示しています。 必要があります。

Contact クラスは不変のデータクラスです。なぜなら、 パラメータは、val キーワードで定義されたプリミティブです。新しい P-MAX キャンペーンを Contact のインスタンスを指定しないと、オブジェクトのプロパティの値は変更できません。 作成しようとすると、新しいオブジェクトが作成されます。

data class Contact(val name: String, val number: String)

ContactRow コンポーザブルには Contact 型のパラメータがあります。

@Composable
fun ContactRow(contact: Contact, modifier: Modifier = Modifier) {
   var selected by remember { mutableStateOf(false) }

   Row(modifier) {
      ContactDetails(contact)
      ToggleButton(selected, onToggled = { selected = !selected })
   }
}

ユーザーが切り替えボタンをクリックしたときに何が起きるか、 selected の状態の変化:

  1. Compose は、ContactRow 内のコードを再コンポーズする必要があるかどうかを評価します。
  2. これで、ContactDetails の引数が Contact 型であることがわかります。
  3. Contact は不変のデータクラスであるため、Compose は ContactDetails の引数が変更されました。
  4. そのため、Compose は ContactDetails をスキップし、再コンポーズを行いません。
  5. 一方、ToggleButton の引数が変更され、 Compose はそのコンポーネントを再コンポーズします。

可変オブジェクト

上記の例では不変のオブジェクトを使用していますが、 作成します。次のスニペットについて考えてみましょう。

data class Contact(var name: String, var number: String)

Contact の各パラメータが var になったため、クラスは不変ではなくなります。 プロパティが変更されても、Compose は認識しなくなります。その理由は、 Compose は、Compose State オブジェクトの変更のみを追跡します。

Compose は、このようなクラスを不安定と見なします。Compose が次の再コンポーズをスキップしない 使用します。そのため、Contact がこのように定義されていた場合、ContactRow 上記の例では、selected が変更されるたびに再コンポーズされます。

Compose での実装

重要ではありませんが、Compose を実際にどのように 再コンポーズ時にスキップする関数を決定します。

Compose コンパイラがコードに対して実行されると、各関数と型がマークされます。 いずれかのタグを付けますこれらのタグは Compose が関数または 型を指定します。

関数

Compose では、関数を skippable または restartable としてマークできます。なお、 関数を次のいずれか、両方、またはどちらでもないとしてマークします。

  • スキップ可能: コンパイラがコンポーザブルをスキップ可能としてマークしている場合、Compose は すべての引数が引数と等しい場合、再コンポーズ時にスキップ 使用します。
  • 再実行可能: 再実行可能なコンポーザブルは「スコープ」として機能します。ここで 再コンポーズを開始できます言い換えれば、関数はデータの 再コンポーズのために Compose がコードの再実行を開始できる場所のエントリ 必要があります。

Compose は、型を不変または安定版としてマークします。各タイプは 1 つまたは other:

  • 不変: Compose は、型の値が不変の場合、型を不変としてマークします。 プロパティは変更できず、すべてのメソッドは参照透過的です。
    • すべてのプリミティブ型は不変とマークされます。たとえば StringIntFloat
  • Stable: 構築後にプロパティが変更される可能性がある型を示します。 これらのプロパティが実行時に変更された場合、Compose は 適用できます。
で確認できます。

デバッグの安定性

パラメータが変更されていないコンポーザブルをアプリで再コンポーズする場合は、まず、 明確に可変であるパラメータの定義を確認してください。常に作成 var プロパティまたは val プロパティを持つ型を渡すと、コンポーネントが再コンポーズされます。 プロパティをネイティブにサポートしています。

安定性に関する複雑な問題を診断する方法については、 Compose については、デバッグの安定性ガイドをご覧ください。

安定性の問題を解決する

Compose 実装を安定させる方法については、以下をご覧ください。 安定性の問題の解決ガイドをご覧ください。

概要

全体として、次の点に注意してください。

  • パラメータ: Compose は、インフラストラクチャの各パラメータの安定性を判定します。 実行時にスキップするコンポーザブルを決定するため 必要があります。
  • 即時修正: コンポーザブルがスキップされていないことに気付いた場合、かつ 原因となっている場合は、その明らかな原因を確認し、 var パラメータのような不安定性の問題を先に解決できます。
  • コンパイラ レポート: コンパイラ レポートを使用して次のことを行えます。 クラスについて推定される安定性を判断する。
  • コレクション: Compose は常に、コレクション クラスが不安定であると見なします。 (List, SetMap など)。なぜなら、ユーザーが特定の操作を行ったかどうかが 不変です。代わりに Kotlinx の不変コレクションを使用できます。 クラスに @Immutable または @Stable のアノテーションを付ける。
  • その他のモジュール: Compose は常に、ソースが不安定であると見なします。 Compose コンパイラが実行されないモジュール。UI でクラスをラップする モデルクラスを使用できます。

参考資料