Así es Electron: el último intento del desarrollo híbrido en una carrera que ya han ganado las apps nativas

Así es Electron: el último intento del desarrollo híbrido en una carrera que ya han ganado las apps nativas

30 comentarios Facebook Twitter Flipboard E-mail
Así es Electron: el último intento del desarrollo híbrido en una carrera que ya han ganado las apps nativas

Desarrollo híbrido contra desarrollo nativo. Un dilema que viene sucediendo en el mundo del desarrollo iOS desde el año 2010. Y un dilema que lleva unos cuantos años también en el mundo del escritorio con una herramienta: Electron. Tan alabada por unos como criticada por otros. Electron es el último intento de la comunidad open source de aprovechar toda la sinergia de desarrolladores web para atraerlos al mundo de las aplicaciones, en este caso, de escritorio. Una bandera ondeada por Microsoft como dueña de GitHub y precursora de esta librería.

Pero, ¿qué es eso del desarrollo híbrido o nativo? ¿Por qué el primero permite hacer una app que funcione por igual con mínimas modificaciones tanto en iOS como Android? ¿Un desarrollo nativo no puede ser multiplataforma? ¿Es el desarrollo nativo solo el que se hace con la SDK oficial de cada sistema, creada por Apple o Google, según sistema? Vamos a adentrarnos un poco en este controvertido tema intentando explicar qué es cada cosa.

Conceptos de framework y desarrollo híbrido o nativo

Una librería o framework es aquella que nos permite crear una app para algún sistema usando sus componentes. En el caso de iOS, la librería oficial de Apple para desarrollo se llama Cocoa Touch y tiene varios componentes, varias librerías: desde UIKit que nos permite construir interfaces pasando por otras muchas para diferentes funcionalidades como sonido, red, acceso a funciones del sistema y mucho más. Esta librería es nativa. Pero lo es no porque sea la oficial creada por Apple, lo es por cómo está construida y cómo dibuja las interfaces.

Estructura de Cocoa Touch presentada en la primera versión de la SDK del iPhone
Estructura de Cocoa Touch presentada en la primera versión de la SDK del iPhone

El concepto fundamental que se maneja en el ideario común es que una app nativa es aquella que está hecha con las librerías oficiales de cada sistema. Si hago la app con Cocoa Touch y uso Swift u Objective-C, es nativa de Apple. Si la hago con la SDK de Android y uso Kotlin o Java entonces es nativa de Android. Pero esto no es así exactamente. Tenemos que entender dos conceptos fundamentales: el primero, cómo dibujamos la interfaz de nuestra app y dos, ¿permite mi app ser ejecutada en más de un sistema a la vez con mínimas modificaciones?

Tenemos que distinguir que una cosa es una app híbrida y otra que sea multiplataforma. Normalmente todas las tecnologías híbridas son multiplataforma, pero también tenemos tecnología nativa que igualmente es multiplataforma. Al final, que todos los sistemas y hardware funcionen sobre C facilita ejecutar código en diferentes sistemas.

Veamos el ejemplo de un videojuego con Unity: cuando hago un juego con esta herramienta, lo que obtengo es un desarrollo nativo para cada plataforma soportada que no solo incluye iOS o Android, también todas las consolas como Xbox One, PS4 o Switch, además de PC, Mac o Linux. En realidad lo que hace Unity es aprovechar la compatibilidad de todos los sistemas con código binario en C++ para crear "un paquete" del juego desarrollado, que será leído y ejecutado por la librería del propio Unity que hay creada para cada sistema que lo soporta.

El quid de la ejecución multiplataforma hoy día es que cada sistema crea una librería compatible con cada sistema (iOS, Android, PC, consolas...) y lanza "un programa" que dicha librería puede interpretar y ejecutar independientemente del sistema. Esta librería "traduce" o "interpreta" el contenido.

Pero la ejecución es nativa por dos motivos: porque se ejecuta contra el motor gráfico del sistema directamente (ya sea OpenGL ES, Vulkan o Metal, según plataforma o compatibilidad de dispositivo) y porque las llamadas que pueden requerir componentes del sistema, son traducidas en tiempo real para ir contra los componentes nativos de cada sistema: su librería oficial. Si yo pongo un campo de texto en Unity para la interfaz, este se traducirá al elemento nativo de la librería oficial de cada sistema desde su llamada.

En esa misma premisa existe, por ejemplo, la librería Xamarin de Microsoft. Crea apps nativas, tecnológicamente hablando, porque lo que hace es traducir las llamadas propias a las que tiene el sistema. Y una de las opciones que nos permite Xamarin es usar sus propios componentes a través de la librería llamada Xamarin.Forms. Este tipo de desarrollo tiene un buen rendimiento y es competente. Pero además tiene algo extra: que crea apps multiplataforma (no híbridas). Un solo desarrollo funciona en más de un sistema.

Mobile Web, Hybrid Native y Pure Native

¿Entonces qué es una app híbrida? Es cuando la app mezcla tecnologías nativas con una interfaz que en realidad es una página web que no está dibujada directamente en el sistema. Por eso la palabra híbrida. Es capaz de usar componentes nativos de cada sistema mediante traducción como hace Unity o Xamarin, pero la interfaz se está dibujando en una ventana de navegador, no contra un lienzo del motor gráfico del sistema. Por lo tanto las interfaces se crean usando HTML y no con instrucciones gráficas del sistema.

Una app híbrida o nativa se diferencian por las tecnologías que usan para construir la interfaz de usuario. Una app híbrida permite hacer llamadas a librerías propias de cada sistema, pero construye la interfaz con HTML5, como una página web y sobre una ventana que es un navegador web "camuflado". Una librería nativa, construye las interfaces directamente con las librerías gráficas del sistema.

Que un librería híbrida luego sea multiplataforma, es una característica de la misma, pero no tiene nada que ver la una con la otra. Podría existir una librería híbrida para iOS, que solo funcionara en iOS. Sería híbrida pero no multiplataforma.

La historia del híbrido en iOS

Hasta el año 2010, la única forma de crear apps para iOS era usando Xcode y Objective-C. Nadie había creado otra solución, de cualquier tipo, que fuera capaz de generar un código binario que pudiera ejecutarse como app en un iPhone. Pero entonces, en la presentación del iPad, Steve Jobs comenzó su guerra con Adobe Flash. Flash no era soportado. La ejecución de Flash requería poner una máquina virtual en el equipo con derecho de administración del sistema iOS, lo que hubiera tenido dos consecuencias: la primera lastrar el rendimiento del sistema (si dicha librería no está bien desarrollada) y la segunda es que cualquier fallo de seguridad en el motor de Flash permitiría obtener permisos de administración en un iPhone y saltarse toda su seguridad. Por ese motivo Apple no acepta máquinas virtuales como Flash o Java.

A mediados de 2010, no carente de polémica, Apple prohibió durante unos meses que pudieran subirse apps al App Store que no estuvieran desarrolladas en Xcode, programadas en Objective-C y usando su librería oficial Cocoa Touch.

Pero en aquel momento Flash tenía mucho peso en la industria, así que Adobe se puso a trabajar y creó una app llamada Flash Builder, que permitía coger un desarrollo hecho en Flash y ejecutarlo en un iPhone como una app. Una traducción. En realidad un contenedor híbrido que ejecutaba el motor de Flash en un navegador dentro de la app. Al conocerse esto, Steve Jobs tomó una decisión tajante: las normas del App Store cambiaron y se prohibió subir ninguna app que no estuviera desarrollada en Objective-C y creada con Xcode. Pero lo más importante: obligaba a usar las librerías oficiales como única opción. Esto pasó en abril de 2010 y esta norma no cambió hasta verano. Apple quitó esta restricción de forma silenciosa gracias a Epic Games, creadores del motor Unreal Engine.

Project Sword en su presentación con iOS 4.1
Project Sword en su presentación con iOS 4.1

El motivo fue uno de peso: el equipo de Epic presentó a Apple una increíble demo técnica que luego fue presentada en el evento de septiembre de 2010 dedicado a los iPod que usaba el truco que había usado Adobe. El juego se llamaba Project Sword y supuso la publicación ese mismo día de la demo técnica Epic Citadel que unos meses más tarde se convertiría en el primer Infinity Blade (ahora ya desaparecido). Una demo que técnicamente ejecutaba el motor Unreal contra la librería Stage3D de Flash, que permite aceleración 3D en juegos. Un motor que se ejecutaba en iOS contra un navegador oculto al usuario usando la tecnología WebGL de gráficos 3D para navegadores. Así que a Apple no le quedó otra que quitar la restricción pues le acababan de demostrar que el desarrollo híbrido, multiplataforma y el usar otras librerías (como la misma Flash) dentro de una app, era una apuesta de futuro que no podían rechazar. Así que Apple quitó esa norma y desde entonces han ido apareciendo multitud de herramientas o librerías que permiten crear apps para iOS, aparte de la oficial de Apple.

El híbrido llega al escritorio: Electron

¿Por qué existen las apps híbridas? ¿Qué sentido tiene querer crear una interfaz usando HTML5 en vez de una interfaz dibujada de forma nativa en el sistema? Simple: casi el 72% del total de desarrolladores del mundo, lo son de web. Por lo tanto, la forma más rápida de aprovechar a esa masa crítica de desarrolladores para hacer apps para sistemas móviles, era darles herramientas que les permitieran, con lo que ya saben y alguna cosa más, crear apps móviles. Así de simple.

Pero de esa forma, al igual que una página web se ve igual sea cual sea el sistema donde lo ves, una app híbrida mostrará la misma interfaz sea cual sea el sistema donde se ejecute. Aunque no respete con ello las directrices y el lenguaje de diseño de cada plataforma.

El principal problema de una app híbrida, en cuanto a diseño de interfaces, es que no respeta las directrices de diseño de cada plataforma, que es lo que hace que sepamos usar una app de forma intuitiva nada más arrancarla.

Toda esta revolución de aprovechar la sinergia de tantos desarrolladores también tuvo su traslación al mundo escritorio de la mano de GitHub, ya que se creó una necesidad que antes no existía: crear apps multiplataforma para sistemas de escritorio que permitieran consumir servicios que principalmente viven en la nube. Como Slack, Skype, Spotify... o incluso crear editores de texto o código que también tuvieran un único desarrollo, como Visual Studio Code o Atom. Y para ello se creó Electron.

Electron App

Pero, ¿qué es Electron? Pues básicamente es un motor Chromium (el que usa Google Chrome) que tiene dentro además una capa de ejecución de javascript Node.js. Está creado por GitHub (ahora propiedad de Microsoft) y permite encapsular una página web dentro de un contenedor que le permite “parecer” una app nativa de escritorio sin serlo. Un motor que ahora es muy criticado por su alto consumo de recursos en el sistema y su ineficiente rendimiento, pero que permite crear una app con un solo desarrollo de forma relativamente rápida, que podrá ser ejecutada en cualquier sistema Windows, Linux o macOS. Y como librería híbrida, permite conectar con algunos servicios del sistema que le permiten integrarse mejor en su ejecución (componentes nativos de cada sistema).

Pero esto tiene un problema muy grande. Imaginen esto: tenemos abierto Visual Studio Code (el editor de código más usado hoy día) porque estamos editando código, Slack porque trabajamos con un equipo de gente en línea y Spotify porque estamos oyendo música. Sin saberlo, tenemos 3 Google Chromes abiertos a la vez consumiendo recursos y memoria. Y si abrimos Google Chrome, 4. El hecho que las apps Electron sean auto-contenidos no les permite compartir recursos.

Como las apps de Electron están encapsuladas para que el mismo desarrollo funcione en Windows, Mac o Linux, no pueden compartir recursos. Así que cada app crea su propia instancia del motor Chromium unido a Node.js.

Si queremos hacernos una idea del alcance que tiene este hecho, solo tenemos que ver un caso práctico: un editor de texto como Sublime Text abriendo un fichero de C de 4 líneas necesitará alrededor de 40MB de memoria para funcionar. Con un editor en modo texto como VIM, apenas 5MB. Pero si usamos Visual Studio Code, necesitará 349MB. Una locura.

Si usamos plugins que aumenten la funcionalidad del editor y abrimos un fichero de 6MB en formato XML, VIM usará apenas 12MB mientras Visual Studio Code 392MB. Aparte del consumo de CPU. Y por mucho que intenten optimizar el código, no servirá para mucho porque el problema está en el núcleo: en el motor. En crear encapsulado un motor Chromium con Node.js y cargarlo con cada app de forma independiente. Todo para “ahorrarse” hacer un desarrollo nativo en cada plataforma y aprovechar a desarrolladores web para todo ello sin tener que formarlos en la tecnología de cada sistema.

Electron está enfocado por las compañías que lo usan como un intento de ahorro en dos frentes: la dificultad de encontrar desarrolladores para entornos como macOS o Linux (en Windows es “más fácil”) y no tener que hacer 3 apps diferentes con 3 equipos diferentes de desarrollo.

Este tipo de “problemas” no suelen llegar al usuario final y muchas veces culpamos a la propia Spotify que su app para escritorio sea tan lenta y consuma tantos recursos, o que para mostrar un álbum y cuatro elementos tengamos que encender la gráfica dedicada de nuestro equipo o se caliente la CPU. Pero en realidad, la culpa de Spotify es indirecta porque la verdadera culpa de este problema la tiene la tecnología tras esta app.

Mejor ser nativo que híbrido

Las apps multiplataforma pueden ser mejores o peores según la librería. Ahí los dos grandes ganadores son Xamarin y Flutter. Una de Microsoft, la otra de Google. El problema aquí son las híbridas que para poner la interfaz en una web, consumen más recursos y no se adaptan al lenguaje de diseño del sistema ni su usabilidad, son más lentas y además les cuesta adaptarse correctamente a cambios como el notch y su zona segura.

Además una app híbrida, al tener la interfaz basada en un intérprete de HTML5, CSS y javascript, tiene más posibilidades de tener fallos de seguridad que al ser explotados pongan en peligro nuestro sistema. Electron, de hecho, ha tenido varios fallos históricamente (ya resueltos) que permitían explotar vulnerabilidades que daban acceso completo a nuestros equipos. Y un fallo de estos supone la actualización del motor por parte de cada app de forma independiente.

Al usar tecnología web para mostrar las interfaces, las apps híbridas se exponen a más fallos de seguridad que el resto de apps pues tienen un componente más expuesto a posibles fallos.

Independientemente de la decisión estratégica, todo el mundo del desarrollo sabe que cuanto más te pegas al sistema (usas librerías nativas y oficiales) menos recursos consume una app, más eficiente es y más usable. Tal vez lleve más tiempo (o no, depende de cada caso) pero la calidad estará muy por encima.

La forma más clara de ver el desarrollo nativo contra el híbrido
La forma más clara de ver el desarrollo nativo contra el híbrido

Usar librerías híbridas hace que tengas apps más pesadas para el sistema, como Facebook que está desarrollada en React Native, una librería híbrida creada por la propia Facebook y que es uno de los motivos por los que dicha app es el monstruo que es en consumo de recursos, memoria o almacenamiento. Una app nada optimizada que ni siquiera borra la caché que ella misma genera. Por fortuna, la tendencia profesional es a darse cuenta, cada día más, que la tecnología híbrida que prometía abaratar costes al final no los abarata tanto y la calidad final del producto dista mucho de un desarrollo nativo para Android o iOS.

Progressive Web Apps

Pero sigue habiendo una gran masa de desarrolladores insistiendo que hacer una interfaz como una página web es lo mejor a pesar de tener todas las pruebas en su contra (a mi modo de ver). Es mucho más fácil y rápido. Lo es, tienen razón. Pero también menos eficiente y mucho peor su resultado final. Y de mantener a cambios en las plataformas. Tan convencidos están que ahora existen una nueva tendencia llamada PWAs (o Progressive Web Apps) que pretende que las apps ya no se necesiten instalarse en el sistema. Que se pueda ejecutar una app directamente sobre el navegador web y con ello eliminar el problema de tracción que supone para una empresa el tener que llevar al App Store a sus usuarios para que instalen sus apps. Pero esto supondría dar acceso a todos los componentes del sistema a una página web. ¿Estaríamos dispuestos a ello? Yo no, desde luego.

Como desarrollador con más de 30 años de experiencia, 10 años en el entorno Apple, en mi experiencia y en mi opinión, el desarrollo híbrido es una rémora importante para el desarrollo en sí. Y desde mi opinión, más vale un producto de calidad que uno de mala que “nos promete” ahorrar costes (que habría que analizar esto detenidamente). Las apps son el futuro y el presente de muchos servicios y qué mejor que dar la mejor experiencia a nuestros usuarios. Jamás entenderé que un servicio que vive en las apps use tecnologías híbridas que intenten abaratar costes y reduzcan calidad cuando lo que necesitas es dar la mejor experiencia a tus usuarios.

Por suerte Apple ya nos ha adelantado la llegada de Marzipan a macOS, que seguramente permita una buena tracción de desarrolladores en iOS hacia el Mac. Apps iOS creadas nativamente con la librería oficial Cocoa Touch que funcionarán igual en Mac. Y ojo, solo aceptarán este tipo de apps. Nada más. Pero ya hablaremos otro día en profundidad de Marzipan.

Comentarios cerrados
Inicio