Modo de omisión seguro

La función de omisión sólida 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 pueden omitir.
  • Se recordan las lambdas con capturas inestables.

Cómo habilitar el modo de omisión seguro

Para habilitar la omisión fuerte para un módulo de Gradle, incluye la siguiente opción en el bloque composeCompiler de tu configuración de Gradle:

composeCompiler {
   enableStrongSkipping = true
}

Posibilidad de omitir el elemento componible

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

Con la opción de omisión segura habilitada, todas las funciones de componibilidad reiniciables se pueden omitir. Esto se aplica sin importar si tienen parámetros inestables o no. Las funciones de componibilidad que no se pueden reiniciar no se pueden omitir.

Cuándo omitirlos

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 quieras que un elemento componible inhabilite la función de omisión fuerte. Es decir, te recomendamos que uses un elemento que admite composición reiniciable, pero que no se pueda omitir. En este caso, usa la anotación @NonSkippableComposable.

@NonSkippableComposable
@Composable
fun MyNonSkippableComposable {}

Anota las clases como estables

Si deseas que un objeto use la igualdad de objeto en lugar de la igualdad de instancia, sigue 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 con lambda

El modo de omisión sólido también permite una mayor memorización de lambdas dentro de los elementos componibles. Con la opción de omisión fuerte habilitada, se recordará automáticamente cada expresión lambda dentro de una función de componibilidad.

Ejemplos

Para lograr la memorización de lambdas dentro de elementos componibles cuando se usa la omisión sólida, el compilador une tu lambda con una llamada 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 claves siguen las mismas reglas de comparación que las funciones de componibilidad. El entorno de ejecución compara claves inestables mediante la igualdad de instancias. Compara las claves estables con la igualdad de objetos.

Memorización y recomposición

Esta optimización aumenta en gran medida la cantidad de elementos componibles que el tiempo de ejecución omite durante la recomposición. Sin 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 lambda nueva tiene parámetros que no son iguales a la última composición. Esto da como resultado la recomposición.

Evita la memorización

Si tienes una expresión lambda que no deseas memorizar, 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 sólida habilitada, el compilador marca casi todos los elementos componibles como que se pueden omitir y une todas las lambdas en una remember{...}. Por lo tanto, habilitar el modo de omisión seguro tiene un impacto muy pequeño en el tamaño del APK de la aplicación.

La habilitación de la omisión fuerte 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 antes no se podían omitir y que estaban presentes en la app determinada, pero deberían ser relativamente menores.