Rendimiento de Compose

Jetpack Compose tiene como objetivo ofrecer un rendimiento excelente listo para usar. En esta página, se muestra cómo escribir y configurar tu app para obtener el mejor rendimiento, y se indican algunos patrones que debes evitar.

Antes de leer esta página, te recomendamos que te familiarices con los conceptos fundamentales de Compose en Acerca de Compose.

Configura tu app de forma correcta

Si el rendimiento de tu app es deficiente, es posible que haya un problema de configuración. Un buen primer paso es revisar las siguientes opciones de configuración.

Compila en el modo de lanzamiento y usa R8

Si tienes problemas de rendimiento, asegúrate de ejecutar tu app en el modo de lanzamiento. El modo de depuración es útil para detectar muchos problemas, pero implica un costo de rendimiento significativo y puede dificultar la detección de otros problemas de código que podrían afectar el rendimiento. También debes usar el compilador R8 para quitar el código innecesario de tu app. De forma predeterminada, la compilación en modo de lanzamiento usa automáticamente el compilador R8.

Usa un perfil de Baseline

Compose se distribuye como biblioteca, en lugar de formar parte de la plataforma de Android. Este enfoque nos permite actualizar Compose con frecuencia y admitir versiones anteriores de Android. Sin embargo, la distribución de Compose como biblioteca implica un costo. El código de la plataforma de Android ya está compilado e instalado en el dispositivo. Por otro lado, las bibliotecas se deben cargar cuando se inicia la app y se deben interpretar en el momento en que se requiere la funcionalidad. Esto puede ralentizar la app al inicio y cada vez que use una función de la biblioteca por primera vez.

Para mejorar el rendimiento, define los perfiles de Baseline. Estos perfiles definen las clases y los métodos necesarios para los recorridos críticos del usuario y se distribuyen con el APK de tu app. Durante la instalación de la app, ART compila ese código crítico con anticipación para que esté listo para usarse cuando se inicie la app.

No siempre es fácil definir un buen perfil de Baseline y, por ello, Compose se envía con uno de forma predeterminada. Es posible que no tengas que realizar ninguna tarea para ver este beneficio. Sin embargo, si decides definir tu propio perfil, es posible que generes uno que, en realidad, no mejore el rendimiento de la app. Debes probar el perfil para verificar que te ayude. Una buena forma de hacerlo es escribir pruebas de macrocomparativas para tu app y verificar los resultados de estas mientras escribes y revisas tu perfil de Baseline. Si deseas obtener un ejemplo a fin de escribir pruebas de macrocomparativas para tu IU de Compose, consulta este ejemplo de Compose.

Si quieres obtener un desglose detallado de los efectos del modo de lanzamiento, R8 y los perfiles de referencia, consulta la entrada de blog en la que se explican lasrazones por las que siempre deberías probar el rendimiento de Compose en el lanzamiento.

Cómo afectan al rendimiento las tres fases de Compose

Como se explica en Fases de Jetpack Compose, cuando Compose actualiza un fotograma, atraviesa por tres fases:

  • Composición: Compose determina qué mostrar; ejecuta funciones que admiten composición y compila el árbol de IU.
  • Diseño: Compose determina el tamaño y la posición de cada elemento en el árbol de IU.
  • Dibujo: En realidad, Compose renderiza los elementos individuales de la IU.

Compose puede omitir de manera inteligente cualquiera de esas fases si no es necesaria. Por ejemplo, supongamos que un solo elemento gráfico cambia entre dos íconos del mismo tamaño. Como ese elemento no cambia de tamaño y no se agregan ni quitan elementos del árbol de IU, Compose puede omitir las fases de composición y diseño, y solo volver a dibujar ese elemento.

Sin embargo, algunos errores de codificación pueden dificultar que Compose sepa las fases que puede omitir con seguridad. Si hay dudas, Compose termina ejecutando las tres fases, lo que puede causar que tu IU sea más lenta de lo necesario. Por lo tanto, muchas de las prácticas recomendadas de rendimiento se relacionan con ayudar a Compose a omitir las fases que no necesita hacer.

Se deben seguir algunos principios generales que pueden mejorar el rendimiento en general.

Primero, cuando sea posible, quita los cálculos de las funciones que admiten composición. Es posible que se deban volver a ejecutar las funciones que admiten composición cada vez que cambia la IU; cualquier código que coloques en el elemento que admite composición se volverá a ejecutar, potencialmente, para cada fotograma de una animación. Por lo tanto, debes limitar el código del elemento que admite composición a lo que realmente necesita para compilar la IU.

Y, en segundo lugar, aplaza las lecturas de estado el mayor tiempo posible. Si mueves la lectura de estado a un elemento secundario que admite composición o a una fase posterior, puedes minimizar la recomposición, o bien omitir la fase de composición por completo. Para ello, puedes pasar las funciones lambda en lugar del valor de un estado que cambia con frecuencia y puedes priorizar los modificadores basados en lambda cuando pasas un estado de este tipo. Puedes ver un ejemplo de esta técnica en la sección Aplaza las lecturas el mayor tiempo posible.