Skip to main content
Loading...

WebAssembly

Inspiring technology by Hunters

En esta ocasión, nuestros Hunters nos hablan de WebAssembly, o WASM, es una tecnología que está revolucionando el desarrollo web y la ejecución de aplicaciones, tanto en el navegador como en el servidor. Con la promesa de ofrecer un rendimiento casi nativo y la posibilidad de utilizar lenguajes compilados como C, C++ o Rust, WASM se posiciona como una herramienta fundamental para abordar tareas intensivas y mejorar la experiencia del usuario en la web.

¿Qué es WebAssembly?

WebAssembly es un formato de instrucciones binarias que se ejecuta en una máquina virtual ligera y diseñada para funcionar junto a JavaScript en los navegadores modernos. Su objetivo es permitir que el código se ejecute a velocidades cercanas a las nativas, gracias a que el proceso de parseo y compilación es mucho más eficiente que el de los lenguajes interpretados tradicionalmente en la web.

Además, WASM no está limitado al entorno del navegador. Con la introducción de WASI (WebAssembly System Interface), se está abriendo la puerta a la ejecución de código en el servidor y en dispositivos embebidos, ofreciendo portabilidad y seguridad a través de entornos de ejecución en sandbox.

Funcionamiento y características técnicas

Formato binario y máquina virtual

  • Formato binario compacto: El código WebAssembly se distribuye en un formato binario (.wasm) que es mucho más pequeño y rápido de cargar y ejecutar en comparación con el código fuente tradicional.
  • Máquina virtual ligera: WASM se ejecuta en una máquina virtual de pila que traduce rápidamente las instrucciones a código máquina, lo que permite obtener un rendimiento casi nativo.
  • Representación textual: Además del formato binario, existe una representación textual (.wat) que facilita la lectura y depuración del código.

Integración con JavaScript 

WASM está diseñado para complementarse con JavaScript. Mientras que el primero se encarga de las operaciones computacionalmente más costosas, JavaScript sigue siendo el encargado de manipular el DOM y la interacción con el usuario. Esto permite combinar lo mejor de ambos mundos en una misma aplicación.

Seguridad y portabilida

Una de las principales ventajas de WebAssembly es que se ejecuta dentro de un entorno aislado (sandbox), lo que evita que el código pueda afectar al sistema huésped sin los permisos adecuados.
 
Además, al ser independiente de la arquitectura, el mismo módulo WASM puede ejecutarse independientemente del dispositivo.

Herramientas similares y alternativas en el mercado

asm.js

Antes de la llegada de WebAssembly, existía asm.js, un subconjunto de JavaScript que permitía a los navegadores ejecutar código de bajo nivel con mejoras en el rendimiento. Aunque asm.js fue un primer paso importante para ejecutar código “casi nativo” en la web, WASM lo ha reemplazado rápidamente gracias a su formato binario más eficiente y a su adopción como estándar del W3C.

Otras alternativas y runtimes

En el ecosistema de WASM, se han desarrollado diversos runtimes:

  • WASI: Una interfaz de sistema que permite ejecutar módulos WASM fuera del navegador, ofreciendo funcionalidades similares a las de sistemas POSIX.
  • Wasmer, Wasmtime y WasmEdge: Son ejemplos de runtimes que permiten ejecutar código WASM en entornos no web, facilitando su uso en aplicaciones serverless, contenedores y sistemas embebidos.
  • Comparativa con contenedores tradicionales: Algunas iniciativas, como runwasi, permiten integrar módulos WASM en entornos de contenedores (por ejemplo, con Docker), aprovechando la ligereza y rapidez de WASM frente a soluciones con contenedores que requieren un sistema operativo completo.

¿Qué aporta WebAssembly?

Rendimiento casi nativo

WASM permite que el código compilado se ejecute con un rendimiento muy cercano al que se podría obtener con una solución nativa. Esto es especialmente útil para aplicaciones que requieren procesar grandes volúmenes de datos, gráficos en 3D o videojuegos.

Multilenguaje y flexibilidad

No se programa directamente en WebAssembly, sino que se escribe en lenguajes de alto nivel (como C, C++, Rust, Go e incluso .NET y Java) que luego se compilan a WASM. Esto abre la puerta a un desarrollo más flexible y permite aprovechar el ecosistema y herramientas existentes de estos lenguajes.

Seguridad

El hecho de que el código WASM se ejecute dentro de un sandbox le otorga un nivel adicional de seguridad, ya que restringe el acceso directo a la memoria y a las funcionalidades del sistema operativo sin la debida autorización. Esto reduce significativamente el riesgo de vulnerabilidades que pudieran comprometer la seguridad del usuario o del sistema.

Portabilidad

Al ser independiente de la arquitectura, un módulo WASM compilado se puede ejecutar en diferentes plataformas y dispositivos sin necesidad de modificar el código, facilitando la portabilidad y el despliegue de aplicaciones de forma universal.

Casos de uso y aplicaciones prácticas

  • Aplicaciones web interactivas: Juegos, editores de imágenes, simulaciones y otras aplicaciones que requieren un procesamiento intensivo pueden beneficiarse del rendimiento mejorado que ofrece WASM.
  • Ejecución en el servidor: Con WASI y runtimes como Wasmer, es posible ejecutar aplicaciones compiladas en WASM en el servidor, dando paso a una nueva generación de aplicaciones serverless y contenedores ultra ligeros.
  • Integración en ecosistemas existentes: Al poder trabajar junto a JavaScript y otros lenguajes, WASM se integra fácilmente en proyectos web modernos. Este enfoque permite aprovechar lo mejor de ambos mundos sin necesidad de reescribir aplicaciones completas desde cero.

Lenguajes de Programación y WebAssembly

Lenguajes compatibles y ampliamente soportados:

  • C y C++: Gracias a herramientas como Emscripten y Clang, estos lenguajes se han convertido en la base para muchos proyectos WASM. Su naturaleza de lenguaje compilado y fuertemente tipado permite generar módulos WASM de alto rendimiento.
  • Rust: Rust es uno de los favoritos en el ecosistema WASM. Su enfoque en la seguridad de memoria y su compatibilidad con LLVM facilitan la compilación a WASM, logrando aplicaciones seguras y con un rendimiento casi nativo.
  • Go: A partir de la versión 1.11, Go incluye soporte experimental para compilar a WASM. Aunque su ecosistema aún está en evolución, permite portar aplicaciones Go al navegador con ciertas limitaciones en comparación con C/C++ o Rust.
  • AssemblyScript: Es una variante de TypeScript diseñada específicamente para compilar a WASM. Permite a los desarrolladores familiarizados con JavaScript y TypeScript aprovechar las ventajas del código compilado, sin tener que aprender un lenguaje completamente nuevo.
  • C# (con Blazor): A través de Blazor WebAssembly, es posible ejecutar aplicaciones escritas en C# directamente en el navegador, combinando la robustez del lenguaje con las ventajas del entorno WASM.

Lenguajes con compatibilidad limitada o que requieren soluciones adicionales:

  • Lenguajes interpretados o de tipado dinámico (por ejemplo, Python, Ruby, PHP): Estos lenguajes no se compilan nativamente a WASM. Sin embargo, existen proyectos como Pyodide (para Python) o Ruby WASM, que permiten portar parte de su funcionalidad al navegador, aunque con ciertos compromisos en términos de rendimiento y tamaño del binario.
  • Java: Aunque Java es un lenguaje ampliamente utilizado, su modelo de máquina virtual y recolección de basura lo hacen menos adecuado para la compilación directa a WASM. Existen iniciativas como TeaVM o CheerpJ que intentan traducir código Java a WASM, pero la integración aún presenta desafíos.

Pruebas

Con el fin de comprobar la funcionalidad de WASM, hemos creado un pequeño banco de pruebas en el que se ejecuta el mismo código de tres maneras diferentes:

  • C compilado con gcc: Utilizando diversas configuraciones.
  • C compilado a WASM mediante Emscripten: Para aprovechar la compilación a un formato binario optimizado.
  • JavaScript puro: Implementando directamente la lógica en el lenguaje web.

El banco de pruebas incorpora funciones representativas que se utilizan habitualmente para evaluar el rendimiento

  • Mandelbrot: Calcula el fractal de Mandelbrot iterando una función matemática en cada píxel para determinar su pertenencia al conjunto, poniendo a prueba cálculos intensivos en punto flotante.
  • N-Body: Simula interacciones gravitacionales entre múltiples cuerpos, evaluando la eficiencia en cálculos numéricos y actualizaciones dinámicas de estado.
  • Spectral Norm: Estima el valor propio dominante de una matriz mediante iteradas multiplicaciones de la matriz y su traspuesta, midiendo operaciones intensivas de multiplicación y aritmética de punto flotante.
  • Binary Trees: Construye recursivamente un árbol binario hasta una profundidad determinada, calcula un checksum mediante su recorrido y libera la memoria, evaluando la gestión de memoria y la eficiencia en funciones recursivas.
Compilación de programa C a .wasm

Compilación de programa C a .wasm

Una vez obtenidos los binarios de WASM, los integramos en nuestro código JavaScript de la siguiente manera, lo que nos permite acceder a las funciones del banco de pruebas.

Importamos nuestros binarios a JavaScript

Importamos nuestros binarios a JavaScript

Resultados del benchmark ejecutado en Microsoft Edge

Resultados del benchmark ejecutado en Microsoft Edge

Resultados en C con y sin mejoras habilitadas en compilación

Resultados en C con y sin mejoras habilitadas en compilación

De los resultados obtenidos se observa una mejora en algunas pruebas al utilizar WASM, aunque sin alcanzar el rendimiento nativo, tal como era de esperar.

No obstante, es importante destacar las posibilidades que WASM ofrece, ya que no solo mejora el rendimiento, sino que también permite utilizar otros lenguajes en el navegador con un desempeño aceptable.

Conclusiones

Aunque existan alternativas como asm.js, la eficiencia y el enfoque modular de WASM, junto con iniciativas como WASI y runtimes modernos, han consolidado su posición como estándar . En definitiva, WASM no solo aporta mejoras en términos de rendimiento y seguridad, sino que también abre un abanico de posibilidades para el desarrollo.

No obstante, surgen desafíos importantes, especialmente en la integración con lenguajes como Java. Las aplicaciones Java dependen en gran medida de sofisticados mecanismos de recolección de basura y de estrategias avanzadas de paralelización, características que son nativas a su entorno de ejecución tradicional (JVM). Adaptar estos elementos al entorno de WASM/WASI implica resolver problemas relacionados con la gestión de memoria y la sincronización de hilos, aspectos en los que la infraestructura actual de WebAssembly aún está en evolución.

En definitiva, mientras WASM y WASI abren un abanico de posibilidades para el desarrollo de aplicaciones híbridas y portátiles, la adaptación de entornos de ejecución tradicionales como el de Java seguirá representando un reto considerable que requerirá innovaciones continuas y colaboración entre la comunidad de desarrolladores.

¿Conoces el programa Hunters?

Ser un hunter es aceptar el reto de probar nuevas soluciones que aporten resultados diferenciales. Únete al programa Hunters y forma parte de un grupo transversal con capacidad de generar y transferir conocimiento.

Anticípate a las soluciones digitales que nos harán crecer. Consulta más información sobre Hunters en la web.

Patricio Flores

Patricio Flores
Técnico de Software
Altia