Modo de omisión seguro

La omisión avanzada es un modo disponible en el compilador de Compose. Cuando se habilita, cambia el comportamiento del compilador de dos maneras:

  • Los elementos componibles con parámetros inestables se vuelven optables.
  • Se recuerdan las expresiones lambda con capturas inestables.

Cómo habilitar el modo de omisión avanzada

Para habilitar el omitición estricta de un módulo de Gradle en una versión anterior, incluye la siguiente opción en el bloque composeCompiler de tu configuración de Gradle:

android { ... }

composeCompiler {
   enableStrongSkippingMode = true
}

Omisión de componibilidad

El modo de omisión fuerte relaja algunas de las reglas de estabilidad que normalmente aplica el compilador de Compose cuando se trata de funciones de omisión y de componibilidad. De forma predeterminada, el compilador de Compose marca una función de componibilidad como omitible si todos sus argumentos tienen valores estables. El modo de omisión fuerte cambia esta situación.

Con la omisión sólida habilitada, todas las funciones de componibilidad reiniciables se pueden omitir. Esto se aplica independientemente de si tienen parámetros inestables. Las funciones de componibilidad que no se pueden reiniciar no se pueden omitir.

Cuándo omitir

Para determinar si se debe omitir un elemento componible durante la recomposición, Compose compara el valor de cada parámetro con sus valores anteriores. El tipo de comparación depende de la estabilidad del parámetro.

  • Los parámetros inestables se comparan con la igualdad de instancias (===)
  • Los parámetros estables se comparan con la igualdad de objetos (Object.equals()).

Si todos los parámetros cumplen con estos requisitos, Compose omite el elemento componible durante la recomposición.

Es posible que desees un elemento componible para inhabilitar la omisión fuerte. Es decir, es posible que quieras un elemento componible que se pueda reiniciar y que no se pueda omitir. En este caso, usa la anotación @NonSkippableComposable.

@NonSkippableComposable
@Composable
fun MyNonSkippableComposable {}

Cómo anotar clases como estables

Si deseas que un objeto use la igualdad de objetos en lugar de la igualdad de instancias, continúa anotando la clase determinada con @Stable. Un ejemplo de cuándo podrías tener que hacer esto es cuando observas una lista completa de objetos. Las fuentes de datos, como Room, asignarán objetos nuevos para cada elemento de la lista cada vez que uno de ellos cambie.

Memorización de Lambda

El modo de omisión estricto también habilita una mayor memoria de las lambdas dentro de elementos componibles. Con la omisión segura habilitada, cada lambda dentro de una función de componibilidad se recordará automáticamente.

Ejemplos

Para lograr la memorización de lambdas dentro de los elementos componibles cuando se usa el omitir forzado, el compilador une tu lambda con una llamada a remember. Está vinculada con las capturas de la lambda.

Considera un caso en el que tienes una lambda, como en el siguiente ejemplo:

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

Con la omisión fuerte habilitada, el compilador memoriza la lambda uniéndola a una llamada remember:

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

Las teclas siguen las mismas reglas de comparación que las funciones de componibilidad. El entorno de ejecución compara claves inestables con la igualdad de instancias. Compara claves estables con igualdad de objetos.

Memorización y recomposición

Esta optimización aumenta en gran medida la cantidad de elementos componibles que el entorno de ejecuciónomite durante la recomposición. Sin la memorización, es mucho más probable que el entorno de ejecución asigne una lambda nueva a cualquier elemento componible que tome un parámetro lambda durante la recomposición. Como resultado, la expresión lambda nueva tiene parámetros que no son iguales a la última composición. Esto genera una recomposición.

Evita la memoización

Si tienes una lambda que no deseas almacenar en caché, usa la anotación @DontMemoize.

val lambda = @DontMemoize {
    ...
}

Tamaño del APK

Cuando se compilan, los elementos componibles que se pueden omitir generan más código que los elementos componibles que no se pueden omitir. Con la omisión fuerte habilitada, el compilador marca casi todos los elementos componibles como que se pueden omitir y une todas las lambdas en un remember{...}. Debido a esto, habilitar el modo de omisión avanzada tiene un impacto muy pequeño en el tamaño del APK de tu aplicación.

Habilitar la omisión importante en Now In Android aumentó el tamaño del APK en 4 KB. La diferencia de tamaño depende en gran medida de la cantidad de elementos componibles que no se podían omitir anteriormente y que estaban presentes en la app determinada, pero debería ser relativamente menor.