強力なスキップモード

強スキップは、Compose コンパイラで使用できるモードです。有効にすると、 次の 2 つの方法でコンパイラの動作を変更します。

で確認できます。

強いスキップモードを有効にする

Gradle モジュールの厳格なスキップを有効にするには、 次のように、Gradle 構成の composeCompiler ブロックに配置します。

android { ... }

composeCompiler {
   enableStrongSkippingMode = true
}

コンポーズ可能な関数のスキップ可能性

強スキップモードにより、通常適用される安定性ルールの一部が緩和される コンポーズ可能な関数のスキップとコンポーズ可能な関数に関しては、Compose コンパイラによって制御されています。方法 デフォルトでは、すべての要素がコンポーズ可能な関数を その引数の値は固定されています。強スキップモードはこれを変更します。

強力なスキップを有効にすると、再実行可能なすべてのコンポーズ可能な関数が スキップ可能これは、不安定なパラメータがあるかどうかにかかわらず適用されます。 再起動できないコンポーズ可能な関数は、スキップできません。

スキップする場合

再コンポーズ時にコンポーザブルをスキップするかどうかを判断するために、Compose は以下を比較します。 各パラメータの値を以前の値と結合します比較のタイプ パラメータはパラメータの安定性に依存します。

  • 不安定なパラメータはインスタンスの等式(===)を使用して比較されます
  • 安定パラメータはオブジェクトの等価性(Object.equals())を使用して比較されます

すべてのパラメータがこれらの要件を満たしている場合、Compose は実行時にコンポーザブルをスキップします。 必要があります。

コンポーザブルで、強制的なスキップをオプトアウトすることもできます。つまり、 コンポーザブルは再実行可能で スキップできませんこの場合は、 @NonSkippableComposable アノテーション。

@NonSkippableComposable
@Composable
fun MyNonSkippableComposable {}

クラスに安定版アノテーションを付ける

インスタンスの等価性ではなくオブジェクトの等価性を使用するオブジェクトが必要な場合は、 指定されたクラスに引き続き @Stable のアノテーションを付けます。たとえば オブジェクトのリスト全体を監視する場合 Room によって、リスト内のすべてのアイテムに対して新しいオブジェクトが割り当てられるので、 変更が反映されます。

ラムダ記憶化

強力なスキップモードにより、ラムダのメモ化も多くなります。 見てみましょう。強力なスキップを有効にすると、 コンポーズ可能な関数は自動的に記憶されます。

強制スキップを使用する際にコンポーザブル内のラムダをメモ化するには、 コンパイラはラムダを remember 呼び出しでラップします。鍵は 呼び出すことができます。

次のようなラムダがあるとします。

@Composable
fun MyComposable(unstableObject: Unstable, stableObject: Stable) {
    val lambda = {
        use(unstableObject)
        use(stableObject)
    }
}

強力なスキップを有効にすると、コンパイラはラムダをメモリ化するために、 remember の呼び出し:

@Composable
fun MyComposable(unstableObject: Unstable, stableObject: Stable) {
    val lambda = remember(unstableObject, stableObject) {
        {
            use(unstableObject)
            use(stableObject)
        }
    }
}

キーは、コンポーズ可能な関数と同じ比較ルールに従います。ランタイム インスタンスの等価性を使用して不安定なキーを比較します。次を使用して安定版の鍵を比較します。 オブジェクトの等価性です

メモ化と再コンポーズ

この最適化により、実行時に生成されるコンポーザブルの数が大幅に増えます。 スキップできるようになります。メモ化をしなければ、ランタイムが 新しいラムダを、作成時にラムダ パラメータを受け取るコンポーザブルに割り当てる 必要があります。そのため、新しいラムダには 続きます。これにより、再コンポーズが行われます。

メモ化を避ける

メモしないラムダがある場合は、@DontMemoize を使用します。 アノテーション。

val lambda = @DontMemoize {
    ...
}

APK サイズ

スキップ可能なコンポーザブルをコンパイルすると、生成されるコードが スキップ可能でない コンポーザブルもありますストロング スキップを有効にすると、コンパイラは ほぼすべてのコンポーザブルをスキップ可能としてマークし、すべてのラムダを remember{...}。このため、強力なスキップモードを有効にすると、 アプリの APK サイズに与える影響を確認できます。

Now In Android で強力なスキップを有効にすることで APK が増えました 4 KB 削減されます。規模の違いは、以前のモデルの数に 特定のアプリには存在しているはずの、スキップできないコンポーザブル 比較的小規模です。