En el artículo anterior vimos que React Native es una excelente alternativa para crear aplicaciones apalancando el código. Esto es debido a que ofrece una arquitectura sólida que permite un performace cercano al nativo.
Este artículo vamos a bucear un poco más en los aspectos de rendimiento, ver cómo podemos comenzar a trabajar con React Native y finalmente revisar algunos casos de uso.
Rendimiento de React Native
Como hemos comentado, React Native permite alcanzar un rendimiento similar al nativo.
Esto queda patente en el experimiento que hizo John A. Calderaio y que explica en su post “Comparing the Performance between Native iOS (Swift) and React-Native”.
En el artículo compara dos aplicaciones idénticas, una hecha en Swift para IOS y otra hecha en React Native. La aplicación tiene cuatro pestañas:
- Perfil, que solicita al usuario que inicie sesión en Facebook, recupera la foto de perfil, el nombre y el correo electrónico del usuario y mostrarlos en la página.
- Lista de tareas pendientes y será una lista fácil de usar utilizando NSUserDefaults (memoria interna del iPhone). Tiene funciones de “agregar” y “eliminar” elementos.
- Visor de página y consistirá de un Controlador de vista de página. El Controlador de vista de página tendrá tres pantallas que el usuario puede deslizar (slide).
- Mapas y consistirá en una Vista de mapa de la ubicación actual del usuario, con un punto azul en el mapa que representa la ubicación del usuario.
Esta aplicación es lo suficientemente simple para montala en los dos lenguajes, y suficientemente compleja para permitir comparar la CPU, la GPU, el uso de memoria y el uso de energía de cada aplicación.
Los resultados son muy interesantes:
Mediciones de CPU
Como se puede ver en las distintas pestañas, el performance de RN es muy similar al de la aplicación Swift, incluso en dos de ellas (perfil y todo) es superior.
Mediciones de GPU
El segundo conjunto de datos son las mediciones de la GPU. Se realizó una tarea por cada pestaña, para Swift y React Native. El eje vertical llega a 60 frames/segundo. Cada segundo la herramienta “Core Animation” grabará una medición. Se tomó el promedio de estos y se trazó en la siguiente tabla.
Una vez más, Swift gana dos pestañas y React-Native gana en otras dos (perfil y vista de página). Sin embargo, React-Native gana esta categoría en general por .95 frames/s. Es sorprendente el rendimiento que Facebook ha podido extraer de React-Native, que como se ve, resiste frente al iOS nativo (Swift).
Mediciones de Memoria
Otra vez se hizo una tarea por pestaña y se midió cada mili segundo usando la herramienta “Allocations”.
React-Native gana tres pestañas de cuatro. En general, React-Native usó 61.96 MiB menos memoria. “Mapas” usó por mucho la mayor cantidad de memoria en cada caso.
Conclusiones
Es sorprendente cómo React Native es capaz de llegar a cotas de rendimiennto cercanas a las de una aplicación nativa, en este caso IOS y en alguos casos de uso incluso ser mejor.
Para mejorar el rendimiento, los desarrolladores de facebook nos dan algunas pistas en el artículo “Dive into React Native performance”:
- Limpiar Requires/Babel helpers (impacto alto)
- Evitar copiar y decodificar cadenas al cargar el paquete (impacto medio)
- Desmontar módulos de solo DEV (impacto bajo)
- Generar descripciones de eventos en el servidor (impacto bajo)
- Lazy requieres (impacto bajo)
- Lectura de caché incremental (impacto alto)
- Llamadas de puente de dosificación, llamadas de retransmisión por lotes (impacto alto)
- Flushing temprao de IU (impacto bajo)
- Carga lenta de módulos nativos (impacto bajo)
- Enlaces táctiles lazy en componentes de texto (impacto bajo)
Tal como explican los propios desarrolladores: ”estas mejoras son solo el comienzo: seguimos trabajando para que cada parte de la pila sea más rápida, desde el tiempo de análisis de JavaScript hasta el rendimiento de obtención de datos”.
Primeros pasos con React Native
Comenzar con React Native es muy sencillo. Si ya tenemos instalada node y npm, podemos instalar el cli de React Native con la siguiente orden:
npm install -g react-native-cli
A partir de aquí podemos crear una apliación con la siguiente orden
react-native init MyFirstRNApp
Teniendo en cuenta que tenemos nuestro android conectado al ordenador o un emulador; nos movemos dentro del proyecto y podemos hacer correr la aplicación con la orden.
cd MyFirstRNApp react-native run-android
Esto instalará la aplicación en nuestro dispositivo (o abrirá el emulador).
Si queremos activar el live reload, accederemos al menú de la aplicación y marcaremos la opción.
Además, hay un servidor de desarrollo ejecutándose en nuestra terminal:
Nos ayudará en la recarga en vivo del servidor. Necesitamos mantenlo abierto, no lo cerreis.
Después de compilar el proyecto, veremos nuestro terminal principal algo como esto.
Ahora, abriremos el proyecto en nuestro editor favorito. Visual Studio Code tiene un excelente soporte para React Native.
La estructura del proyecto es similar a esta:
Crear componentes
Necesitamos mostrar una vista de inicio de sesión; por eso primero estamos crearemos la vista de Login.js dentro de la carpeta de componentes.
mkdir components cd components
Dentro crearemos el componente Login.js
import React, { Component } from 'react'; import { AppRegistry, Text, View, StyleSheet, Image, TextInput } from 'react-native'; const styles = StyleSheet.create({ image: { width: 100, height: 100, alignSelf: 'center' }, input: { height: 50, width: 200, marginTop: 30, padding: 4, fontSize: 18, borderWidth: 1, borderColor: 'green' } }); export default class Login extends Component { render() { return ( <View> <Image style={styles.image} source={require('../images/login.png')} /> <TextInput style={styles.input} placeholder="Username" /> <TextInput style={styles.input} placeholder="Password" secureTextEntry={true} /> </View> ) } }
Aquí, primero hemos importado el componente React. Luego, hemos introducido algunos elementos de la formuario de RN.
Igual que sucede en React.js, el componente de inicio de sesión tiene el método render() que genera la vista de nuestra aplicación.
Utilizamos el componente Text, TextInput, View, e Image. Hay muchos otros componentes listos para usar que puede usar en el proyecto.
La referencia de componentes se pueden consultar en la documentación de API de componentes de React Native.
En React Native, podemos añadir diseño a un componente particular. Simplemente asignamos la clave a ese elemento, y esa clave se usa para asignale estilos, tal como se hace en css3.
Importar Login.js en App.js
Importaremos el componente de login dentro del componente raíz de igual manera que se hace en React.
Después de guardar el archivo, en el simulador se verá la pantalla siguiente.
React Native y Redux
Redux es un contenedor de estado predecible para aplicaciones JavaScript.
Ayuda a escribir aplicaciones que se comportan de forma coherente, se ejecutan en diferentes entornos (cliente, servidor y nativo) y son fáciles de probar. Además de eso, ofrece una gran experiencia de desarrollador, como la edición de código en vivo combinada con un depurador de viaje en el tiempo.
Redux es el complemente ideal para React porque le aporta la gestión de estados de la aplicación y permite entrelazar la vista con la lógica de negocio siguiendo el patrón Flux. La pregunta que sigue sería si React Native se puede usar con Redux.
Y la respuesta es un Sí rotundo. Jon Lebensold ofrece un artículo muy interesante para comenzar a usar React Native con Redux en “Getting Started with React Native & Redux” en el cual nos muestra paso a paso cómo podemos interconectar Redux con los componentes de React Native.
Tal como el muestra, el proceso no es muy diferente del que seguiríamos con React.js. En mi experiencia personal, el resultado es igualmente espectacular: además de permitir implementar el patrón Flux (en realidad una simplificación del mismo), Redux permite que el rendimiento de nuestra aplicación no se vea prácticamente afectada y se siga acercando al de las aplicaciones Nativas.
Casos de uso de React Native
React Native se presentó a los desarrolladores como el siguiente paso para crear aplicaciones móviles.
No obstante React Native no es la solución definitiva para cualquier tipo de aplicación.
React Native es ideal para aplicaciones no muy complejas que se fundamenten sobre todo en interfaces y funcionalidades simples.
Especialmente en las que se necesite generar aplicaciones en entornos web, además de entornos nativos Android e IOs.
Este caso esta bien ilustrado en el artículo de Christian Sepulveda: “Share Code between React and React Native Apps” en el que explica cómo se puede compartir arquitectura entre una apliación web (SPA) hecha con React y una apliación React Native. Además es tremendamente interesante por el hecho de abordar la refactorización de componentes con estado a componentes stateless, lo cual es base para la reutilziación de la parte de lógica de negocio.
Para aplicaciones más complejas, muy probablemente haga falta combinarla con desarrollos nativos. Sobre todo para casos complejos en los que haga falta usar fuertemente APIs nativas.
Aunque siempre se puede usar puentes (bridges), no es algo que sea óptimo, y por tanto no se recomienda hacer. Para mantener el rendimiento de su aplicación, estas llamadas deben reducirse al mínimo.
En siguiente artículo de Railsware se pueden ver casos de ejemplo de aplicaciones creadas con React Native.
Asimismo en el siguiente post se puede ver 5 casos de uso en forma de aplicaciones de código libre hechas en React Native y de las cuales se puede aprender buenas lecciones:
Especialmente recomendable el caso del “Facebook’s F8 Conference App”.
Reflexiones finales
Tal como hemos visto, React Native ofrece un rendimiento espectacular cercano a las aplicaciones nativas. Esta característica, unida a la facilidad de crear interfaces de usuario usando los mismo mecanismos de React, hace que sea una opción a tener en cuenta para aplicaciones no muy complejas.
Crear aplicaciones con React Native es realmente sencillo y tiene como beneficio el apalancamiento del know-how que se pueda tener en Javascript y en React.js. Con un equipo más pequeño se puede generar una aplicación para tres entornos: Android, IOs y Web.
Esto hace que React Native sea idea para casos de uso en que necesitemos tener una aplicación en estos tres escenarios.
Uniendo React Native con Redux podemos lograr aplicaciones consistentes en los tres entornos, que sean fáciles de controlar y testar, con grandes rendimientos.
Asimismo, los casos de uso de React Native son amplios, pero sobre todo debemos tener en cuenta que son recomendables para aplicaciones que no usan de modo intensivo las APIs nativas.