webAssembly — La web sin monopolio 🏘

El título de este artículo seguramente te inquietó un poco, si es así has trabajado con JavaScript para interactuar con cualquier navegador y crear aplicaciones web, JavaScript ha monopolizado la web desde hace mucho tiempo, pero tranquilo eso es cosa del pasado.

Antes de comenzar quiero aclarar que JavaScript no desaparecerá de la web, al contrario tanto JavaScript y webAssembly trabajarán de la mano para hacer una web mucho más fuerte, rápida y demasiado llamativa para programadores, que tal vez no conozcan nada acerca de JavaScript o simplemente no interactúen con este lenguaje.

Pero qué es webAssembly, su definición oficial es un formato binario de bajo nivel, pero creo que esta definición se queda corta o no es muy fácil de comprender en un inicio, trataré de explicarlo no tan literalmente, para mi WA es dar la posibilidad de que la web pueda ejecutar más de un lenguaje de programación, como lo son C++ y RUST a través de un proceso de ensamblaje, con este proceso mejoraremos el performance o la velocidad de nuestras aplicaciones y tenemos un sin fin de nuevas mejoras e innovación que podemos realizar en la web.

“Actualmente la web es una utopía hecha realidad, puedo ver a Messi y Cristiano jugando en el mismo equipo” 💪🏽

Para explicar algo siempre me gusta hablar de su historia, ya que esto te dará un mejor contexto y entenderemos el porqué de las cosas, empecemos hablando de JavaScript:

JavaScript fue creado en una semana dicho por su propio creador en 1995, este lenguaje no fue diseñado para ser rápido en un inicio, de hecho pasó por un período fantasma donde no tuvo crecimiento e innovación, solo hasta el 2008 donde se mejoró el performance gracias a los JIT COMPILER, los cuales son una mejora al motor de compilación de JavaScript para que este pueda compilar en tiempo de ejecución, esto despertó el interés de muchos programadores y da inicio a una era llamada la “guerra del performance”.

Esta guerra de performance trajo con ella muchas nuevas mejoras e innovaciones, por ejemplo podemos ejecutar JavaScript en lado del servidor con Node, crear aplicaciones de escritorio con Electrón, podemos crear sitios web híbridos implementando Progressive Web Apps, donde podemos combinar lo mejor de la web y las aplicaciones móviles, hace poco escribí un post del porqué crear webs progresivas, puedes echarle un ojo y por último un sin fin de frameworks y librerías.

Ahora que conocemos la historia y cómo ha evolucionado JavaScript, hablemos de WebAssembly. Este fue anunciado en el año 2015, en 2016 se realiza el primer demo apoyado por empresas reconocidas, como Google, Microsoft y Mozilla, la principal característica de WebAssembly es su velocidad siendo mucho más rápido que JavaScript, demasiado rápido diría yo, para entender más detalladamente porque WA es mas rápido que JavaScript, es necesario que entiendas cómo funciona el navegador. Existen dos formas para que el navegador entienda nuestro código y lo ejecute, esto se hace a través de un intérprete o un compilador, ambos cumplen con el objetivo y hacen relativamente lo mismo, toman el lenguaje humano y lo traducen a lenguaje máquina (lenguaje binario), para que el navegador pueda entenderlo, veamos como funciona cada uno y cuales son sus diferencias.

Intérprete:

Un intérprete funciona leyendo línea por línea, esto quiere decir que cuando se termina de interpretar una línea de código, automáticamente la ejecuta en el navegador, este proceso tiene sus ventajas y una de ellas es su velocidad en la ejecución, el interprete se asemeja mucho a como funciona JavaScript, es por esta razón que todos los navegadores en su inicio utilizaban intérpretes, pero también tiene sus desventajas ya que por ejemplo si en el código llegase a existir un bucle, el interprete tendrá que ejecutar una y otra vez la misma línea de código, creando tiempos innecesarios y haciendo que una página web sea lenta.

Compilador:

Este funciona de una manera totalmente distinta ya que en vez de leer línea por línea, primero se toma el tiempo de leer todo el código y luego enviar en un solo bloque la traducción en binario al navegador, para que este lo ejecute, este proceso tiene su desventaja ya que se toma demasiado tiempo en ejecutar nuestro código, pero tiene ventajas a un nivel de performance, ya que al tomarse un tiempo para leer el código, puede hacer cambios para evitar problemas como redundancias, estos cambios se llama optimizaciones.

Estas son las dos formas utilizadas para que el navegador entienda el código escrito en lenguaje humano, cuando hablé de historia de JavaScript, mencioné los JIT COMPILERS, los JITs fueron una mejora muy importante que se le hizo al motor de JavaScript, es la combinación entre los interpretes y los compiladores, toma lo mejor de cada uno dando un resultado positivo para la web, ya que funciona de la siguiente manera:

Primeramente en el motor de JavaScript se implementa un monitor que se encarga de orquestar la lectura del código y su traducción, en primera instancia el monitor envía al intérprete a leer el código, ya que este es mucho mas rápido que el compilador, si el monitor se da cuenta que el interprete está leyendo la misma línea varias veces, eso quiere decir que hay un bucle en código, entonces el compilador realiza un extracción de ese fragmento del código, para procesarlo en un segundo plano con el fin de dar vía libre al interprete, para que este pueda seguir con la lectura y ejecutando rápidamente el código, puede que diferentes navegadores funcionen diferente pero esta es una idea global del funcionamiento actual de un navegador.

¿Dónde encaja webAssembly en todo esto ?

Para responder esto hablemos del performance que es lo que destaca a WebAssembly, alguna vez has escuchado que “el código más rápido es el que no se usa” esto tiene sentido cuando estás buscando mejorar algo, si analizamos el proceso de traducción entre el lenguaje humano a máquina, este proceso de traducción toma demasiado tiempo y es por este motivo que la web es lenta, como lo viste en la explicación que acabo de dar, con WebAssembly omitimos este paso de traducción ya que directamente se le da al navegador un lenguaje que entiende (lenguaje binario), acortando tiempos de ejecución, según experimentos realizados con WA como formato binario es 20x mas rápido que JavaScript.

Como funciona webAssembly

Empecemos con lo primordial hablando del proceso de ensamblaje, donde podemos tomar el código escrito en C/C++ y pasarlo a un formato binario, este formato binario es es un archivo .wasm que no es completamente binario pero se acerca y para el navegador le es mucho mas fácil procesarlo, dentro de este archivo encontraremos módulos que definen funciones que podemos invocar desde JavaScript, los navegadores sólo soportan JavaScript por lo tanto su API no proporciona soporte de bajo nivel, el creador de JavaScript Brendan Eich dio a conocer un compilador intermediario el cual se encarga de ser el puente entre el código escrito en C/C++ y el ensamble wasm, este compilador proporciona la posibilidad de acceder a APIs de bajo de nivel.

En pocas palabras con WebAssembly ahora podemos hacer todo lo que no está al alcance con JavaScript, ya que no tendría sentido validar un formulario con WA, esta tarea JS la hace a la perfección, pero si hablamos de implementar realidad aumentada dentro de una pagina web, WebAssembly puede hacerlo sin problema, ese es el poder que nos ofrece y un fin de nuevas innovaciones vendrán para la web.

Te preguntarás: ¿Cómo puedo utilizar webAssembly en mi aplicación ?

Existen dos formas que conozco, la primera es escribir código directamente en el formato wasm, sinceramente no lo recomendaría es bastante complejo y adicionalmente es mejor escribir código desde un lenguaje confiable, flexible y que brinde un buen soporte como C/C++ o RUST, la otra manera es utilizar una herramienta llamada emscripten que básicamente se encarga de hacer el trabajo duro de crear un módulo wasm partiendo de un código base escrito en C/C++, otra ventaja al utilizar emscripten es que te genera un archivo JavaScript que te permitirá conectarte con la APIs de bajo nivel y te proporciona un acceso fácil a los módulos que creaste en C, todo esto suena algo tedioso de hacer ya que no hay forma llamar un módulo wasm directamente en nuestro JavaScript, como un módulo de npm, pero a futuro esto se podrá hacer lo cual me parece genial.

Vamos a realizar un ejemplo sencillo:

Primero instalaremos emscripten, en la página están las instrucciones para llevar esto acabo según el sistema operativo que estés usando, cuando termines los pasos ejecuta el siguiente comando en tu terminal para verificar que este correctamente instalado:

./emcc -v

Ahora vamos escribir nuestras primeras líneas en C, donde vamos a crear una función que se encargue sumar, pero esta función recibirá un parámetro desde JavaScript y retornará un nuevo valor.

Crea un archivo app.c y copia las siguientes lineas de código, este código como puedes darte cuenta tenemos una función llamada suma, que recibe por parámetros un número, para luego retornar la suma de este número más 10.

#include <stdio.h>
#include <stdlib.h>
#include <emscripten/emscripten.h>
int main() {
printf("WebAssembly module loaded\n");
}
int EMSCRIPTEN_KEEPALIVE suma(int number) {
return number + 10;
}

Ahora con emscripten vamos a realizar el ensamble a el formato binario de nuestro código, ejecutando la siguiente linea en tu terminal:

./emcc app.c

Podrás ver que emscripten generó dos archivos a.out.js y a.out.wasm , anteriormente dije que emscripten realizaba el trabajo duro por nosotros, por esta razón tenemos un archivo JavaScript el cual tiene la conexión con el ensamblaje que se encuentra en a.out.wasm, ahora vamos utilizarlo de la siguiente manera crea un archivo html y carga el archivo JavaScript generado, adicionalmente crea otro archivo JavaScript que también será cargado, en mi caso es test-wa.js desde este llamaremos nuestra función que creamos en C.

<html>
<body style="font-size: 40px;">
</body>
<script src="a.out.js"></script>
<script src="test-wa.js"></script>
</html>

En nuestro archivo test-wa.js vamos a invocar el módulo creado desde webAssembly, de la siguiente manera:

Module['onRuntimeInitialized'] = function() {
var divtest= document.createElement("div");
divtest.innerHTML = "webAssembly es genial: " + Module._suma(10);
document.body.appendChild(divtest)
};

Con el código anterior con una función que nos proporciona emscripten, podemos saber si el modulo ya fue cargado, para tener acceso a la función suma que creamos en C, básicamente creo un div, inserto un `string` llamando a la función suma y le pasamos un parámetro, en este caso el número que queremos añadir a la suma y luego agregamos ese div al DOM, si abres tu archivo html podrás ver algo como esto:

En este momento acabas de crear tu primer modulo en webAssembly y lo utilizaste en JavaScript, felicitaciones. 🎉🎊

Casos de uso para webAssembly:

Este es un listado simple, de posibles cosas que podrías realizar hoy mismo con webAssembly:

  • Renderizar Juegos realizados en Unity o Unreal Engine.
  • Realidad Aumentada.
  • Software CAD: Es decir puedes traer herramientas que fueron hechas para hardware con APIs de bajo nivel, un ejemplo es AUTOCAD para ver esto más detalladamente, haz click aquí.
  • Cifrado de información.
  • Machine Learning: El autoAprendizaje que deriva de la inteligencia artificial.

Conclusión:

webAssembly es el presente y futuro para la web, porque el incremento de programadores que están adoptando esta tecnología en sus aplicaciones va en aumento, en un futuro no muy lejano podremos llamar módulos de webAssembly cómo lo hace npm con JavaScript y Node, obviamente JavaScript no desaparecerá ya que estas dos tecnologías tienen una aplicación y enfoque muy diferente, según las necesidades y requerimientos que tengas puedes aplicar una o la otra. Te invito a que investigues más sobre este tema y estés al tanto de cada mejora y proceso de evolución que esta tenga, en futuro te va servir y lo necesitarás seguramente, espero este artículo te haya ayudado como introducción e iniciación a una tecnología que confío va revolucionar la web.

Gracias por tomarte tu tiempo de leer este artículo ❤️.