クラスが不安定でパフォーマンスが発生した場合 安定版にすべきですこのドキュメントでは、Google Cloud で できます。
強力なスキップを有効にする
まず、強力なスキップモードを有効にしてみてください。強スキップモード 不安定なパラメータを持つコンポーザブルをスキップできます。これは、 メソッドです。
詳しくは、強いスキップをご覧ください。
クラスを不変にする
不安定なクラスを完全に不変にすることもできます。
- 不変: プロパティの値を取得できない型を示します。
その型のインスタンスが作成された後に変更され、すべてのメソッドが
参照します。
- クラスのすべてのプロパティが
var
ではなくval
であることを確認します。 不変型です String, Int
やFloat
などのプリミティブ型は常に不変です。- これが不可能な場合は、Compose の状態を使用して 削除することもできます。
- クラスのすべてのプロパティが
- Stable: 可変型を示します。Compose ランタイムは その型のパブリック プロパティまたはメソッドのいずれかが、 前の呼び出しとは異なる結果が得られます。
不変のコレクション
Compose がクラスを不安定とみなす一般的な理由は、コレクションです。前述のとおり
[安定性の問題を診断する] ページ(Compose コンパイラ)
List, Map
や Set
などのコレクションが、
変更不可とマークされ、不安定な状態としてマークされます。
この問題を解決するには、不変のコレクションを使用します。Compose コンパイラ には、Kotlinx の不変コレクションのサポートが含まれています。これらの コレクションは不変であることが保証されており、Compose コンパイラはそれらを できます。このライブラリはまだアルファ版であるため、API が変更される場合があります。
「安定性の診断」セクションの不安定なクラスについて、もう一度考えてみましょう。 問題に関するガイド:
unstable class Snack {
…
unstable val tags: Set<String>
…
}
不変のコレクションを使用して、tags
を安定版にすることができます。クラスで、
tags
から ImmutableSet<String>
への型:
data class Snack{
…
val tags: ImmutableSet<String> = persistentSetOf()
…
}
そうすると、クラスのすべてのパラメータは不変になり、Compose は コンパイラがクラスを安定版としてマークします。
Stable
または Immutable
でアノテーションを付ける
安定性の問題を解決するには、不安定なクラスにアノテーションを付けることをおすすめします。
@Stable
または @Immutable
に置き換えます。
クラスにアノテーションを付けると、コンパイラによるアノテーションがオーバーライドされる
推論できます。これは、
Kotlin の !!
演算子。あなたは
アノテーションの使い方に注意してください。コンパイラ動作のオーバーライド
コンポーズ可能な関数が再コンポーズされないなど、予期せぬバグを
確認します。
アノテーションなしでクラスを安定させることができる場合は、 安定性が確保される場合があります。
次のスニペットは、 immutable:
@Immutable
data class Snack(
…
)
@Immutable
アノテーションと @Stable
アノテーションのどちらを使用する場合でも、Compose コンパイラ
Snack
クラスが安定版としてマークされます。
コレクション内のアノテーション付きクラス
List<Snack>
型のパラメータを含むコンポーザブルについて考えてみましょう。
restartable scheme("[androidx.compose.ui.UiComposable]") fun HighlightedSnacks(
…
unstable snacks: List<Snack>
…
)
Snack
に @Immutable
アノテーションを付けても、Compose コンパイラはマークします。
HighlightedSnacks
の snacks
パラメータが不安定です。
コレクション型については、パラメータはクラスと同じ問題に直面します。
Compose コンパイラは、場合でも List
型のパラメータを常に不安定としてマークする
それが安定した型のコレクションである場合です
個々のパラメータを安定版としてマークしたり、注釈を付けたりすることはできません。 常にスキップ可能にします進むべき道は複数あります。
不安定なコレクションの問題を回避するには、いくつかの方法があります。 以降のサブセクションでは、これらのさまざまなアプローチの概要を説明します。
構成ファイル
コードベースの安定性に関する契約に従う場合は、
Kotlin コレクションを安定版と見なすことを有効にするには、
kotlin.collections.*
を
安定性構成ファイル。
不変のコレクション
不変性をコンパイル時の安全性を確保するために、
List
の代わりに kotlinx のイミュータブル コレクションを使用します。
@Composable
private fun HighlightedSnacks(
…
snacks: ImmutableList<Snack>,
…
)
Wrapper
不変のコレクションを使用できない場合は、独自のコレクションを作成できます。そのためには、
アノテーション付きの安定版クラスで List
をラップします。汎用ラッパーは多くの場合、
最適な選択肢を選びます
@Immutable
data class SnackCollection(
val snacks: List<Snack>
)
これをコンポーザブルのパラメータの型として使用できます。
@Composable
private fun HighlightedSnacks(
index: Int,
snacks: SnackCollection,
onSnackClick: (Long) -> Unit,
modifier: Modifier = Modifier
)
解決策
これらのアプローチのいずれかを採用すると、Compose コンパイラは
HighlightedSnacks
コンポーズ可能な関数を skippable
と restartable
の両方として。
restartable skippable scheme("[androidx.compose.ui.UiComposable]") fun HighlightedSnacks(
stable index: Int
stable snacks: ImmutableList<Snack>
stable onSnackClick: Function1<Long, Unit>
stable modifier: Modifier? = @static Companion
)
再コンポーズの際に、Compose が HighlightedSnacks
をスキップできるようになりました。
確認します。
安定性構成ファイル
Compose Compiler 1.5.5 以降では、
がコンパイル時に提供可能であると見なします。これにより
標準ライブラリ クラスなど、自分で制御していないクラス
LocalDateTime
などが安定版です。
構成ファイルは、1 行に 1 つのクラスを含む書式なしテキスト ファイルです。コメント 単一および二重のワイルドカードがサポートされています。 構成の例を以下に示します。
// Consider LocalDateTime stable
java.time.LocalDateTime
// Consider kotlin collections stable
kotlin.collections.*
// Consider my datalayer and all submodules stable
com.datalayer.**
// Consider my generic type stable based off it's first type parameter only
com.example.GenericClass<*,_>
この機能を有効にするには、構成ファイルのパスを Compose に渡します。 オプションを提供します。
Groovy
kotlinOptions {
freeCompilerArgs += [
"-P",
"plugin:androidx.compose.compiler.plugins.kotlin:stabilityConfigurationPath=" +
project.absolutePath + "/compose_compiler_config.conf"
]
}
Kotlin
kotlinOptions {
freeCompilerArgs += listOf(
"-P",
"plugin:androidx.compose.compiler.plugins.kotlin:stabilityConfigurationPath=" +
"${project.absolutePath}/compose_compiler_config.conf"
)
}
Compose コンパイラはプロジェクト内の各モジュールで個別に実行されるため、次のことができます。 必要に応じてモジュールごとに異なる構成を提供します。または、1 つの 構成ファイルを作成し、そのパスを各プロジェクトの 説明します。
複数のモジュール
もう一つの一般的な問題は、マルチモジュール アーキテクチャです。Compose コンパイラ クラスが安定しているかどうかを推測できるのは、そのすべての非プリミティブ型が 参照は、stable として明示的にマークされているか、 Compose コンパイラでもビルドできます。
データレイヤーが UI レイヤーとは別のモジュールにある場合、 という問題があるかもしれません。
解決策
この問題を解決するには、次のいずれかの方法を使用できます。
- コンパイラ構成ファイルにクラスを追加します。
- データレイヤー モジュールで Compose コンパイラを有効にするか、クラスにタグを付ける
必要に応じて
@Stable
または@Immutable
に置き換えます。- これには、データレイヤーへの Compose の依存関係の追加が含まれます。ただし、
Compose ランタイムの依存関係にすぎず、
Compose-UI
。
- これには、データレイヤーへの Compose の依存関係の追加が含まれます。ただし、
Compose ランタイムの依存関係にすぎず、
- UI モジュール内で、データレイヤー クラスを UI 固有のラッパーでラップする 。
外部ライブラリが Compose コンパイラ。
すべてのコンポーザブルをスキップ可能にすべきではない
安定性に関する問題を修正する場合、すべての変更を スキップ可能実施しようとすると、時期尚早な最適化につながる可能性があります。 修正するよりも多くの問題を引き起こしかねません。
スキップ可能にしても実際にはメリットがないケースは数多くあります コードの保守が困難になります例:
- 再コンポーズの頻度が低い、またはまったく再コンポーズされないコンポーザブル。
- それ自体がスキップ可能なコンポーザブルを呼び出すだけのコンポーザブルです。
- コストの高い等しいパラメータが多数あるコンポーザブル あります。この場合、パラメータが存在するかどうかを 安価な再コンポーズのコストを上回る可能性があります。
コンポーザブルがスキップ可能の場合、多少のオーバーヘッドが発生します。 できます。コンポーザブルにアノテーションを付けて、再起動不可にすることもできます。 再実行可能であることに気付いたら、