Skip to main content
EngineeringProduct Building

Flutter en Producción: Lo que Aprendimos Después de Lanzar 3 Aplicaciones Multiplataforma

Mortgy
5 min read

Flutter es nuestra opción predilecta para aplicaciones multiplataforma. Hemos lanzado tres aplicaciones Flutter en producción durante el año pasado: una aplicación fintech, una plataforma edtech y una herramienta de servicio de campo. Cada una nos enseñó algo nuevo sobre qué hace bien Flutter y dónde necesitas tener cuidado. Estas son las lecciones reales, no el discurso de marketing.

Gestión de estado: nos decidimos por Riverpod

Después de probar Provider, BLoC y Riverpod en diferentes proyectos, hemos estandarizado Riverpod para todo el nuevo trabajo en Flutter. La razón es simple: maneja la inyección de dependencias y la gestión de estado en un único patrón, es seguro en tiempo de compilación (sin errores en tiempo de ejecución por proveedores faltantes), y funciona idénticamente en pruebas.

BLoC es poderoso pero demasiado ceremonial para la mayoría de aplicaciones. El patrón evento-estado añade boilerplate que ralentiza el desarrollo sin beneficios proporcionales para aplicaciones típicas basadas en CRUD y API. Reservamos BLoC para características complejas con estado como la edición colaborativa en tiempo real, donde el flujo explícito de eventos es genuinamente útil.

Nuestra arquitectura Riverpod sigue un patrón de tres capas: los widgets de UI dependen de controladores (StateNotifier o AsyncNotifier), los controladores dependen de repositorios, y los repositorios dependen de fuentes de datos (clientes API, almacenamiento local). Cada capa es independientemente testeable y el gráfico de dependencias es explícito.

Rendimiento: la regla del 90%

Flutter te ofrece 60fps de forma predeterminada para el 90% de las pantallas. El otro 10% — listas largas con desplazamiento, animaciones complejas superpuestas sobre datos en vivo, y pantallas con muchas imágenes de red simultáneas — requieren optimización deliberada. Las optimizaciones más impactantes que hemos encontrado:

Utiliza constructores const en todas partes posible. Esta práctica única previene reconstrucciones innecesarias de widgets y es la victoria de rendimiento más fácil en Flutter. La aplicamos mediante reglas de lint. Usa ListView.builder en lugar de ListView para cualquier lista más larga de 20 elementos — construye perezosamente solo los elementos visibles. Almacena en caché imágenes de red con cached_network_image y establece límites de memoria apropiados. Para animaciones complejas, usa RepaintBoundary para aislar operaciones de pintura costosas.

El overlay de rendimiento de Flutter DevTools es tu mejor aliado. Lo ejecutamos en cada pantalla durante el desarrollo e identificamos cualquier fotograma que tarde más de 16ms. La mayoría del lag proviene del layout thrashing (widgets profundamente anidados que desencadenan múltiples pases de layout) o reconstrucciones innecesarias (proveedores que notifican a los listeners demasiado ampliamente).

Canales de plataforma: puente hacia código nativo

Toda aplicación Flutter eventualmente necesita código específico de la plataforma. Para nuestra aplicación fintech, fue autenticación biométrica y almacenamiento en enclave seguro. Para nuestra aplicación edtech, fue manejo de notificaciones push con cargas útiles personalizadas. Para nuestra aplicación de servicio de campo, fue seguimiento de ubicación en segundo plano.

Usamos Pigeon para canales de plataforma type-safe en lugar de MethodChannels sin procesar. Pigeon genera el código repetitivo para ambos lados (Dart y nativo) a partir de una única definición de interfaz. Esto elimina la coincidencia de nombres de método basada en cadenas que causa errores en tiempo de ejecución y hace que el código de canales de plataforma sea genuinamente mantenible.

Nuestra regla general: si existe un plugin con puntuación 90%+ en pub.dev y mantenimiento activo, úsalo. Si no, escribe un envoltorio fino de canal de plataforma que delegue a la API nativa. Nunca luches contra la plataforma — acéptala mediante puentes limpios.

Estrategia de testing que realmente funciona

Las herramientas de testing de Flutter son excelentes pero subutilizadas. Nuestra pirámide de testing: 60% pruebas unitarias (repositorios, controladores, lógica de negocio), 30% pruebas de widgets (renderizado de componentes e interacción), 10% pruebas de integración (flujos críticos del usuario de extremo a extremo). Esta proporción nos da confianza para refactorizar sin la fragilidad de demasiadas pruebas de integración.

La característica de pruebas de archivo dorado (golden file testing) está subestimada. Para pantallas con layouts complejos, capturamos una instantánea del widget renderizado y comparamos con una imagen de referencia. Esto detecta regresiones visuales que las pruebas unitarias pierden. Ejecutamos pruebas doradas en CI para cada pull request.

¿Volveríamos a elegir Flutter?

Sí, con salvedades. Flutter es el mejor framework multiplataforma disponible hoy en día para aplicaciones que necesitan tanto iOS como Android con una base de código compartida. El lenguaje Dart es productivo y el sistema de widgets está genuinamente bien diseñado. Hot reload hace que la iteración sea rápida.

Pero no es la opción correcta para todo. Las aplicaciones que son 50%+ código específico de plataforma (AR pesado, pipelines de cámara complejos, integración profunda del SO) deberían ser nativas. Las aplicaciones que son principalmente visualización de contenido con mínima interactividad podrían usar React Native o incluso un PWA. Flutter destaca en aplicaciones interactivas impulsadas por datos con necesidades de integración de plataforma moderadas, lo que describe la mayoría de los productos de startups.

Mortgy

Founder & CEO