Estabilidad en Compose

Compose considera que los tipos son estables o inestables. Un tipo es estable si es inmutable, o si es posible que Compose sepa si su valor cambian entre recomposiciones. Un tipo es inestable si Compose no puede saber si su valor ha cambiado entre recomposiciones.

Compose usa la estabilidad de los parámetros de un elemento componible para determinar si Puedes omitir el elemento componible durante la recomposición:

  • Parámetros estables: Si un elemento componible tiene parámetros estables que no tienen cambia, Compose lo omite.
  • Parámetros inestables: Si un elemento componible tiene parámetros inestables, Compose siempre lo recompone cuando vuelve a componer el elemento superior del componente.

Si tu app incluye muchos componentes innecesariamente inestables que Compose siempre cuando se recomponga, es posible que observes problemas de rendimiento y otros problemas.

En este documento, se detalla cómo puedes aumentar la estabilidad de tu app para mejorar y la experiencia general del usuario.

Objetos inmutables

Los siguientes fragmentos demuestran los principios generales detrás de la estabilidad y a la recomposición.

La clase Contact es una clase de datos inmutable. Esto se debe a que todas sus Los parámetros son primitivas definidas con la palabra clave val. Una vez que crees instancia de Contact, no puedes cambiar el valor de las propiedades del objeto. Si intentaras hacerlo, crearías un objeto nuevo.

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

El elemento ContactRow componible tiene un parámetro de tipo Contact.

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

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

Considera lo que sucede cuando el usuario hace clic en el botón de activación y en Cambios de estado de selected:

  1. Compose evalúa si debe recomponer el código dentro de ContactRow.
  2. Ve que el único argumento para ContactDetails es de tipo Contact.
  3. Como Contact es una clase de datos inmutable, Compose está seguro de que ninguno de los argumentos de ContactDetails cambiaron.
  4. Por lo tanto, Compose omite ContactDetails y no lo recompone.
  5. Por otro lado, los argumentos para ToggleButton cambiaron y Compose recompone ese componente.

Objetos mutables

Si bien en el ejemplo anterior se usa un objeto inmutable, es posible crear un objeto mutable. Considera el siguiente fragmento:

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

Como cada parámetro de Contact ahora es un var, la clase ya no es inmutable. Si cambiaban sus propiedades, Compose no lo sabría. Esto se debe a que Compose solo hace un seguimiento de los cambios en los objetos de estado de Compose.

Compose considera que esa clase es inestable. Compose no omite la recomposición de clases inestables. Por lo tanto, si Contact se definiera de esta manera, ContactRow en el ejemplo anterior se recompondrán cada vez que selected cambie.

Implementación en Compose

Puede ser útil, aunque no crucial, considerar con qué exactitud Compose Determina qué funciones omitir durante la recomposición.

Cuando el compilador de Compose se ejecuta en tu código, marca cada función y tipo. con una de varias etiquetas. Estas etiquetas reflejan cómo Compose maneja la función o el tipo de datos durante la recomposición.

Funciones

Compose puede marcar funciones como skippable o restartable. Ten en cuenta que también Marca una función como una, ambas o ninguna de estas:

  • Se puede omitir: Si el compilador marca un elemento componible como que se puede omitir, Compose puede omitirlo durante la recomposición si todos sus argumentos son iguales con su valores anteriores.
  • Reiniciable: Un elemento componible que se puede reiniciar funciona como un "permiso". dónde puede comenzar la recomposición. En otras palabras, la función puede ser un punto de para la que Compose puede comenzar a ejecutar de nuevo el código para la recomposición después de cambios de estado.

Tipos

Compose marca los tipos como inmutables o estables. Cada tipo es uno o el otro:

  • Inmutable: Compose marca un tipo como inmutable si el valor de su las propiedades nunca pueden cambiar, y todos los métodos son transparentes como referencia.
    • Ten en cuenta que todos los tipos primitivos se marcan como inmutables. Por ejemplo: String, Int y Float.
  • Estable: Indica un tipo cuyas propiedades pueden cambiar después de la construcción. Si esas propiedades cambian durante el tiempo de ejecución, Compose tiene en cuenta esos cambios.

Estabilidad de depuración

Si tu app vuelve a componer un elemento componible cuyos parámetros no cambiaron, primero revisa su definición de los parámetros que son claramente mutables. Redactar siempre recompone un componente si pasas un tipo con propiedades var o val. que usan un tipo inestable conocido.

Para obtener información detallada sobre cómo diagnosticar problemas complejos de estabilidad en Compose, consulta la guía Estabilidad de depuración.

Cómo corregir problemas de estabilidad

Para obtener información sobre cómo aportar estabilidad a tu implementación de Compose, consulta lo siguiente: la guía Cómo corregir problemas de estabilidad.

Resumen

En general, debes tener en cuenta los siguientes puntos:

  • Parámetros: Compose determina la estabilidad de cada parámetro de tu de elementos componibles para determinar cuáles debe omitir a la recomposición.
  • Correcciones inmediatas: Si notas que no se omite el elemento componible y lo que está causando un problema de rendimiento, debes verificar las causas obvias de inestabilidad, como los parámetros var primero.
  • Informes del compilador: Puedes usar los informes del compilador para determinar qué estabilidad se infiere de tus clases.
  • Colecciones: Compose siempre considera que las clases de colección son inestables, como como List, Set y Map. Esto se debe a que no se puede garantizar son inmutables. En su lugar, puedes usar colecciones inmutables de Kotlinx. anotar tus clases como @Immutable o @Stable
  • Otros módulos: Compose siempre considera inestable su origen. módulos en los que no se ejecuta el compilador de Compose. Une las clases en la IU las clases de modelo si es necesario.

Lecturas adicionales