
WebAssembly (Wasm) es un formato de instrucción binaria de bajo nivel que se ejecuta a una velocidad casi nativa en los navegadores web modernos. Proporciona un objetivo de compilación para lenguajes como C, C++, Rust y Go, lo que permite que aplicaciones de alto rendimiento (edición de vídeo, renderizado 3D, juegos, simulaciones científicas) se ejecuten en el navegador con un rendimiento comparable al del código nativo.
WebAssembly (Wasm) es un formato de instrucción binaria de bajo nivel que se ejecuta a una velocidad casi nativa en los navegadores web modernos. Proporciona un objetivo de compilación para lenguajes como C, C++, Rust y Go, lo que permite que aplicaciones de alto rendimiento (edición de vídeo, renderizado 3D, juegos, simulaciones científicas) se ejecuten en el navegador con un rendimiento comparable al del código nativo.
Wasm no reemplaza a JavaScript, sino que lo complementa. JavaScript maneja la interfaz de usuario y la interactividad, mientras que Wasm impulsa las rutas críticas para el rendimiento.
JavaScript nunca fue diseñado para informática de alto rendimiento. Es un lenguaje de un solo subproceso, con recolección de basura y tipado dinámicamente. Si bien los compiladores JIT modernos (V8, SpiderMonkey) han hecho que JS sea notablemente rápido, persisten limitaciones fundamentales:
| Limitación | Impacto |
|---|---|
| Escritura dinámica | La verificación de tipos en tiempo de ejecución agrega sobrecarga |
| Recolección de basura | Pausa para ciclos de GC |
| De un solo hilo | No se pueden utilizar CPU de múltiples núcleos (sin Web Workers) |
| Sin SIMD (hasta hace poco) | Más lento para cargas de trabajo paralelas |
| Grandes aplicaciones | Analizar y compilar JS es caro |
| Característica | Beneficio |
|---|---|
| Velocidad casi nativa | El binario compilado se ejecuta entre 10 y 50 veces más rápido que el JavaScript equivalente para tareas de computación intensiva |
| Rendimiento predecible | Sin calentamiento JIT, sin pausas en la recolección de basura |
| Flexibilidad de idioma | Escriba en Rust, C++, Go, Zig o más de 40 idiomas más |
| Zona de pruebas segura | Se ejecuta en un entorno aislado y seguro para la memoria. |
| Portátil | Se ejecuta en cualquier navegador, servidor, IoT y dispositivo integrado moderno |
| Tamaño de archivo pequeño | El binario Wasm suele ser entre un 50 y un 80 % más pequeño que el JS equivalente |
Task JavaScript WebAssembly Native
─────────────────────────────────────────────────────────
Image blur (4MP) 120ms 8ms 5ms
JSON parse (10MB) 45ms 12ms 10ms
Physics simulation 30 FPS 60 FPS 60 FPS
Audio encoding 3.2x realtime 0.8x realtime 0.5x realtime
Video decoding 30 FPS 60 FPS 60 FPS
Source Code (Rust/C++/Go/...) ──► Compiler (wasm-pack, emcc, tinygo)
│
▼
.wasm binary
│
▼
Browser or Runtime
(V8, SpiderMonkey, Wasmtime)
│
▼
Machine Code
// Load and instantiate a WebAssembly module
const response = await fetch('module.wasm');
const bytes = await response.arrayBuffer();
const { instance } = await WebAssembly.instantiate(bytes);
// Call exported functions
const result = instance.exports.add(5, 7);
console.log(result); // 12
Wasm tiene una memoria lineal, una matriz contigua de bytes a la que pueden acceder tanto el módulo Wasm como JavaScript:
// Wasm memory is accessible from JavaScript
const memory = instance.exports.memory;
const buffer = new Uint8Array(memory.buffer, offset, length);
// Write data from JS to Wasm memory
buffer[0] = 42;
// Call Wasm function that reads from memory
instance.exports.process_data(offset, length);
// Read results back
console.log(buffer[0]); // Wasm may have modified it
Rust se ha convertido en el lenguaje más popular para el desarrollo de WebAssembly:
// lib.rs
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
pub fn fibonacci(n: u32) -> u32 {
match n {
0 => 0,
1 => 1,
_ => fibonacci(n - 1) + fibonacci(n - 2),
}
}
#[wasm_bindgen]
pub fn process_image(data: &[u8], width: u32, height: u32) -> Vec<u8> {
// High-performance image processing
data.chunks(4)
.map(|pixel| {
let r = pixel[0] as f32;
let g = pixel[1] as f32;
let b = pixel[2] as f32;
let gray = (r * 0.299 + g * 0.587 + b * 0.114) as u8;
[gray, gray, gray, pixel[3]]
})
.flatten()
.collect()
}
# Build Wasm package
wasm-pack build --target web
# Generated files:
# - pkg/my_wasm_bg.wasm (compiled Wasm binary)
# - pkg/my_wasm.js (JS glue)
# - pkg/my_wasm.d.ts (TypeScript types)
// image_filter.cpp
#include <emscripten/emscripten.h>
extern "C" {
EMSCRIPTEN_KEEPALIVE
void apply_sepia(unsigned char* data, int length) {
for (int i = 0; i < length; i += 4) {
int r = data[i];
int g = data[i + 1];
int b = data[i + 2];
data[i] = (r * 0.393 + g * 0.769 + b * 0.189);
data[i + 1] = (r * 0.349 + g * 0.686 + b * 0.168);
data[i + 2] = (r * 0.272 + g * 0.534 + b * 0.131);
}
}
}
emcc image_filter.cpp -o image_filter.js -s WASM=1 -s EXPORTED_FUNCTIONS='["_apply_sepia"]'
package main
import "syscall/js"
func add(this js.Value, args []js.Value) interface{} {
return js.ValueOf(args[0].Int() + args[1].Int())
}
func main() {
c := make(chan struct{}, 0)
js.Global().Set("wasmAdd", js.FuncOf(add))
<-c
}
tinygo build -o main.wasm -target wasm main.go
| Solicitud | Idioma | ¿Por qué erasmo? |
|---|---|---|
| Figura | C++ (a través de Emscripten) | Representación vectorial en tiempo real |
| Adobe PhotoshopWeb | C++ | Edición de imágenes de escritorio en el navegador |
| Google Earth | C++ | Representación 3D del terreno global. |
| AutoCAD Web | C++ | Modelado CAD en el navegador |
| FFmpeg.wasm | C | Transcodificación de video completamente en el navegador |
Los motores de juegos se compilan en WebAssembly:
# Unity
Build Settings → WebGL → Build
# Unreal Engine
# Supports WebAssembly as a target platform
La interfaz del sistema WebAssembly (WASI) habilita Wasm fuera del navegador:
┌──────────────────────────────────────────┐
│ Serverless Platform │
├──────────────────────────────────────────┤
│ Cloudflare Workers │
│ ┌──────────┐ ┌──────────┐ ┌─────────┐ │
│ │ Wasm app1│ │ Wasm app2│ │ Wasm... │ │
│ └──────────┘ └──────────┘ └─────────┘ │
│ ┌──────────────────────────────────────┐│
│ │ Fastly Compute@Edge ││
│ └──────────────────────────────────────┘│
│ ┌──────────────────────────────────────┐│
│ │ Fermyon Spin (Nomad) ││
│ └──────────────────────────────────────┘│
└──────────────────────────────────────────┘
Beneficios de Wasm del lado del servidor:
Wasm es ideal para la extensibilidad: las aplicaciones pueden ejecutar complementos aportados por el usuario de forma segura:
// Application engine with Wasm plugin support
fn run_plugin(plugin_bytes: &[u8], input_data: &[u8]) -> Result<Vec<u8>, Error> {
let engine = Engine::default();
let module = Module::new(&engine, plugin_bytes)?;
let store = Store::new(&engine, ());
// Wasm plugin runs in a sandboxed environment
let instance = Instance::new(&store, &module, &[])?;
let result = instance.exports()
.get_typed_function::<(i32, i32), i32>("process")?
.call(&store, (input_ptr, input_len))?;
Ok(read_result_from_memory(result))
}
Ejemplos del mundo real:
| Aspecto | javascript | Asamblea web |
|---|---|---|
| Idioma | Sólo JS | Más de 40 idiomas |
| Ejecución | Interpretado + JIT | binario compilado |
| Actuación | Bueno para la interfaz de usuario | Casi nativo para computación |
| Acceso DOM | Directo | Indirecto (a través de JS) |
| Memoria | Gestionado por GC | Manual (memoria lineal) |
| Tamaño de archivo | Más grande (fuente + minificada) | Más pequeño (binario) |
| Depuración | herramientas maduras | Evolucionando |
| Puesta en marcha | Analizar + compilar (en frío) | Decodificar + compilar (rápido) |
| Seguridad | Zona de pruebas del navegador | Sandbox + seguridad de memoria |
Cuándo usar cuál:
Mejores prácticas: Utilice JS para la capa UI y Wasm para cálculos críticos para el rendimiento.
| Herramienta | Objetivo | Idiomas |
|---|---|---|
| paquete de agua | Cree, pruebe y publique paquetes de Rust Wasm | Óxido |
| Escrito | Compilar C/C++ en Wasm | C, C++ |
| TinyGo | Vaya al compilador con soporte Wasm | Ir |
| wasm-bindgen | Interoperabilidad JS-Wasm de alto nivel | Óxido |
| era hora | Tiempo de ejecución independiente de Wasm (WASI) | cualquier wasm |
| lavadora | Tiempo de ejecución universal de Wasm | cualquier wasm |
| WABT | Kit de herramientas binarias wasm | Asamblea |
# Enable DWARF debug info in Wasm
wasm-pack build --debug
# Browser DevTools support
# Chrome: Sources → WebAssembly → .wasm files
# Firefox: Debugger → WebAssembly
Wasm no puede manipular directamente el DOM. Debe pasar por JavaScript:
// Wasm → JS bridge (currently required for DOM)
// Wasm calls JS function → JS modifies DOM → result back to Wasm
Futuro: Los enlaces WebIDL y la propuesta GC eventualmente permitirán el acceso directo al DOM.
Actualmente, Wasm cuenta con gestión de memoria manual. La propuesta del CG (etapa 4, prevista para 2026-2027) agregará:
Los subprocesos Wasm son compatibles con los navegadores a través de las operaciones SharedArrayBuffer y Atomic, pero requieren encabezados HTTP específicos:
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp
La depuración de Wasm es menos madura que JavaScript:
El modelo de componentes estandariza cómo interactúan los módulos Wasm:
// Component interface definition
(component
(import "host" "console_log" (func (param string)))
(export "process" (func))
)
Esto permite:
Especificación WASI ampliada que agrega:
| Propuesta | Estado | Impacto |
|---|---|---|
| GC (recolección de basura) | Etapa 4 | Idiomas gestionados en Wasm |
| Enhebrado | Etapa 3 (navegadores) | Verdadero paralelismo |
| Manejo de excepciones | Etapa 3 | Manejo estructurado de errores |
| Optimización de llamadas finales | Etapa 2 | Recursión eficiente |
| Control de memoria | Etapa 2 | Gestión de memoria detallada |
| SIMD de ancho fijo | Ya envio | Procesamiento paralelo |
WebAssembly está transformando la web de un visor de documentos a una verdadera plataforma de aplicaciones. Conclusiones clave:
Para la mayoría de los desarrolladores web, la adopción de Wasm puede comenzar con cuellos de botella de rendimiento específicos: procesamiento de imágenes, compresión de datos y cálculos complejos. A medida que las herramientas maduren y los estándares se estabilicen, Wasm se convertirá en una parte estándar de la caja de herramientas de desarrollo web.
Todavía no hay comentarios aprobados. Las respuestas nuevas pueden esperar moderación.