Trabajar con Jetpack Compose implica comprender un fenómeno que puede afectar directamente el rendimiento de nuestras aplicaciones: la recomposición. Aunque la UI declarativa trae múltiples ventajas, ignorar cómo Compose procesa y actualiza la interfaz puede traducirse en experiencias lentas para el usuario y problemas costosos de resolver en el desarrollo.
¿Cuáles son las tres fases de Compose para renderizar la UI?
Compose sigue un diagrama de fases que va desde los datos hasta la interfaz visible. Entender cada fase es fundamental para optimizar el comportamiento de nuestros composables.
¿Qué ocurre en la fase de composición?
En la primera fase, Compose decide qué interfaz de usuario se va a mostrar [0:20]. Se genera un árbol de nodos que referencia cada vista y su jerarquía. Por ejemplo, si tenemos un composable con un Row, un Image, un Column y varios Text, Compose crea nodos internos que representan esa estructura. Lo importante aquí es que cada vez que se produce un cambio de estado, esta fase se ejecuta nuevamente, y es precisamente donde ocurre la recomposición [0:48].
¿Cómo funciona la fase de layout?
La segunda fase utiliza un algoritmo particular donde Compose mide primero los hijos del composable, luego calcula su propia medición con base en el tamaño de esos hijos, y finalmente les asigna una ubicación en coordenadas X e Y [1:03]. Aquí es donde los modifiers entran en acción para aplicar padding, espaciado y posicionamiento. El resultado es una cuadrícula o esqueleto que define cómo se organizan los composables en pantalla.
¿Qué sucede en la fase de renderización?
En la tercera fase, Compose dibuja píxel a píxel cada composable [1:30]. Los nodos ya medidos y posicionados se transforman en una UI visible para el usuario.
¿Por qué la recomposición afecta el rendimiento de tu app?
El fenómeno de recomposición ocurre cuando un cambio de estado provoca que Compose regenere partes del árbol de composición. El problema surge cuando no diseñamos nuestros composables de forma adecuada [2:00].
Imagina una pantalla con dos filas, donde un texto depende de una variable. Si esa variable es accesible para todos los composables del árbol, desde el contenedor principal hasta el último hijo, todo el árbol de composición se regenera desde el inicio [2:20]. En términos de performance, esto es costoso:
- La pantalla del usuario se vuelve lenta.
- El tiempo de desarrollo invertido en resolver problemas aumenta.
- La experiencia de usuario se degrada significativamente.
Usando el Layout Inspector, se puede verificar cuántas veces se recompone cada vista [3:20]. En un ejemplo práctico, al hacer clic repetidamente sobre un composable mal estructurado, el contador de recomposiciones sube rápidamente: cuatro, cinco, seis, siete veces y más [3:50]. En layouts pequeños el impacto puede ser mínimo, pero en interfaces complejas con múltiples fuentes de datos, la diferencia es notable.
¿Cómo optimizar composables para evitar recomposiciones innecesarias?
La clave está en organizar la estructura de componentes y aislar el estado donde realmente se necesita [4:30]. En lugar de que todos los composables tengan acceso directo a la variable de estado, se puede aplicar una separación clara:
- La variable
isShown se envía únicamente al composable que la necesita, en este caso messageText.
- El composable
HelloWorldText modifica la variable a través de una lambda, sin consumirla internamente [4:50].
- De esta forma, la lambda permite que
isShown quede al mismo nivel de la columna sin propagarse hacia abajo.
El resultado es contundente. Al verificar con el Layout Inspector [5:15]:
HelloWorldText escapa la recomposición y muestra recomposiciones saltadas.
- Solo
messageText se recompone porque depende directamente del estado, y eso es el comportamiento natural esperado.
Esta separación produce una UI optimizada donde cada composable se recompone solo cuando es estrictamente necesario. El concepto de estabilidad del estado y la correcta distribución de responsabilidades entre composables son prácticas esenciales para cualquier desarrollo profesional con Compose.
Ahora que conoces las fases de Compose y cómo controlar la recomposición, ¿has experimentado problemas de rendimiento en tus interfaces? Comparte tu experiencia y las estrategias que has aplicado.