Impeller: el motor de rendering de Flutter que reemplaza a Skia en iOS y Android

Si has notado que las animaciones en Flutter van más suaves en los últimos años, parte del mérito es de Impeller, el motor de renderizado que el equipo de Google lleva desarrollando desde 2021 y que reemplaza a Skia. Impeller está habilitado por defecto en iOS desde Flutter 3.10 (mayo de 2023) y en Android desde Flutter 3.19 (febrero de 2024). Esto es lo que hace y por qué importa.

El problema con Skia: la compilación de shaders

Skia, el motor de gráficos que usaba Flutter hasta Impeller, tiene un mecanismo de compilación de shaders just-in-time: la primera vez que necesita dibujar algo complejo, compila el shader en ese momento. Esto causaba el famoso shader compilation jank: un fotograma que se congela brevemente la primera vez que aparece una animación, aunque las siguientes ejecuciones sean fluidas.

Este problema era especialmente visible en iOS, donde las APIs de gráficos (Metal) tienen un proceso de compilación más estricto que OpenGL. Los desarrolladores de Flutter tenían que usar una herramienta de precalentamiento de shaders (shader warm-up) para mitigarlo, lo que añadía complejidad al proceso de build y no siempre funcionaba bien.

Cómo lo resuelve Impeller

Impeller toma un enfoque diferente: en lugar de compilar shaders en tiempo de ejecución, los shaders se precompilan en tiempo de build de la app. Impeller tiene un conjunto fijo y acotado de shaders que cubre todos los casos de uso de Flutter. Al no haber compilación en tiempo de ejecución, el jank de primera ejecución desaparece.

Esto tiene un coste: Impeller solo puede usar los shaders que conoce de antemano. No puede hacer efectos arbitrarios con shaders personalizados como Skia podía. Para el 99% de las apps Flutter esto no es una limitación, pero si usas FragmentShader (los custom shaders de Flutter), hay algunas restricciones adicionales con Impeller.

Impeller en iOS: Metal

En iOS, Impeller usa Metal directamente, la API de gráficos de Apple. Esto tiene varias ventajas: Metal está muy optimizado para el hardware de Apple Silicon, y el path de renderizado de Impeller sobre Metal es más directo que el que tenía Skia (que usaba OpenGL o Metal con una capa de abstracción).

El resultado visible son animaciones más suaves y tiempos de frame más consistentes. En los benchmarks del equipo de Flutter, las apps con Impeller en iOS mostraban un 30-50% menos de fotogramas que superan el presupuesto de 16ms comparado con Skia.

Impeller en Android: Vulkan y OpenGL

En Android, Impeller usa Vulkan en dispositivos que lo soportan (la mayoría con Android 8+) y OpenGL como fallback. La transición fue más lenta que en iOS precisamente por la fragmentación del hardware Android: había más casos extremos que cubrir.

Desde Flutter 3.19, Impeller está habilitado por defecto en Android. Si encuentras algún problema visual en dispositivos específicos, puedes deshabilitarlo temporalmente:

// AndroidManifest.xml — deshabilitar Impeller temporalmente
<application ...>
    <meta-data
        android:name="io.flutter.embedding.android.EnableImpeller"
        android:value="false" />
</application>

Para iOS, el equivalente está en Info.plist:

<!-- Info.plist -->
<key>FLTEnableImpeller</key>
<false/>

En la práctica, deshabilitar Impeller debería ser una medida temporal mientras se reporta el bug al equipo de Flutter, no una solución permanente.

Custom shaders con Impeller

Flutter permite crear efectos visuales con FragmentShader, que usa el lenguaje GLSL. Con Impeller hay algunas limitaciones en las funciones GLSL disponibles, pero los casos de uso más comunes funcionan:

// Cargar y usar un fragment shader
import 'dart:ui' as ui;

Future<void> loadShader() async {
  final program = await ui.FragmentProgram.fromAsset('shaders/my_shader.frag');
  final shader = program.fragmentShader();
  // Usar shader en CustomPainter...
}

Qué cambia para el desarrollador

En la práctica, Impeller es transparente para la mayoría de los desarrolladores: las apps Flutter existentes funcionan exactamente igual con Impeller activado, solo van más suaves. Los cambios visibles son:

  • Desaparece el jank de primera ejecución en animaciones.
  • Las animaciones complejas (transiciones de página, hero animations) son más consistentes.
  • En algunos dispositivos Android de gama baja, el consumo de memoria puede ser ligeramente mayor.

Si usas Flutter DevTools para analizar el rendimiento, la vista de Performance muestra el tiempo de frame con Impeller de la misma forma que con Skia. Lo que cambia es que verás menos picos en la primera ejecución de animaciones.

El futuro: Impeller en Desktop y Web

El roadmap de Flutter incluye llevar Impeller a Desktop (macOS, Windows, Linux) y a Flutter Web. En macOS ya hay trabajo en progreso usando Metal, similar a iOS. En Windows se planea usar Vulkan o DirectX. Estos cambios llegarán en versiones futuras de Flutter.

Para quienes quieren profundizar en cómo detectar y solucionar problemas de rendimiento en Flutter más allá del motor de renderizado, el artículo sobre Flutter y el rendimiento con DevTools cubre las herramientas prácticas de diagnóstico.

Imagen: Pexels / Nana Dua

COMPARTE ESTE ARTÍCULO

COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN LINKEDIN
COMPARTIR EN WHATSAPP