WebAssembly (Wasm) es un lenguaje de bajo nivel con un formato binario compacto que nos permite ejecutar aplicaciones con una performance similar a nativa y que nos ofrece la posibilidad de trabajar con lenguajes como C/C++, C# o Rust en la web.
Está pensado para complementar JavaScript, que dispone de APIs para cargar sus módulos y compartir funcionalidades.
Conceptos básicos de WebAssembly
El principal objetivo de WebAssembly no es escribirse a mano, sino ser compilado desde C, C++, Rust y otros lenguajes de bajo nivel. Su principal virtud es que permite ejecutar código a un rendimiento cercano al nativo. Sus metas son:
- Ser rápido, eficiente y portable.
- Ser legible y fácil de depurar.
- Mantener la seguridad, al ejecutarse en un entorno sandbox.
- No romper la web y mantener la retrocompatibilidad.
La plataforma web
Los principios de la plataforma web incluyen:
- Una máquina virtual (VM) que ejecute el código web (JavaScript, por ejemplo).
- Un conjunto de Web APIs que nos den acceso al control del navegador o el dispositivo.
Las necesidades de la web moderna (aplicaciones complejas, juegos 3D, realidad aumentada...) hicieron que la VM del navegador, tradicionalmente vinculada a JavaScript, encontrara ciertas limitaciones. Es por ello que aparece WebAssembly como un complemento a JavaScript, orientado a resolver los retos más intensivos a nivel de rendimiento.
Conceptos clave de WebAssembly
- Module: representa el binario de WebAssembly que se ha compilado por el navegador a código máquina. No tienen estado y se pueden compartir entre ventanas y workers vía
postMessage()
. Los módulos WebAssembly importan y exportan del mismo modo que los módulos ES. - Memory: representa un ArrayBuffer redimensionable, que contiene las instrucciones de acceso de bajo nivel de WebAssembly.
- Table: representa un array de referencias que no se pueden almacenar en memoria por seguridad o portabilidad.
- Instance: representa el módulo en combinación con el estado que utiliza en runtime, incluyendo la Memory, Table y los valores importados. Es como un módulo ES cargado en una global particular con su conjunto de importaciones.
Dada una instancia de WebAssembly, JS puede llamar a sus exports sícronamente, exponiéndose estos como funciones de JavaScript normales. A su vez, WebAssembly puede ejecutar funciones de JS si se le proporcionan vía import.
¿Cómo se utiliza WebAssembly en una aplicación real?
Podemos escribir directamente WebAssemby a nivel de importador o mediante AssemblyScript, o bien portarlo desde C/C++ o Rust.