spinny:~/writing $ less webassembly-wasm-complete-guide.md
12WebAssembly (WASM) e nato come un modo per eseguire C++ nel browser. Nel 2026, gira ovunque - browser, server, reti edge, dispositivi embedded - e alimenta alcune delle applicazioni piu impegnative del web. Il motore di rendering di Figma, Adobe Photoshop sul web, l'elaborazione video di Google Meet e la piattaforma di calcolo edge di Cloudflare funzionano tutti su WebAssembly.34Chrome Platform Status colloca WASM a circa il 5,5% di tutti i caricamenti di pagina su Chrome all'inizio del 2026, in crescita rispetto al 4,5% dell'anno precedente. Con WASM 3.0 diventato standard W3C e WASI in fase di maturazione verso la versione 1.0, l'ecosistema ha raggiunto un punto di svolta.56Questa guida copre tutto cio che devi sapere per iniziare a sviluppare con WebAssembly.78## Cos'e WebAssembly?910WebAssembly e un formato di istruzioni binarie progettato come target di compilazione. Scrivi il codice in un linguaggio ad alto livello (Rust, C, C++, Go, Kotlin), lo compili in `.wasm` e lo esegui in qualsiasi ambiente che disponga di un runtime WASM - browser, Node.js, Cloudflare Workers, Wasmtime o Wasmer.1112```mermaid13graph LR14 Rust[Rust / C / C++] --> Compiler[Compiler]15 Compiler --> WASM[.wasm Binary]16 WASM --> Browser[Browser V8/SpiderMonkey]17 WASM --> Server[Server Wasmtime]18 WASM --> Edge[Edge Cloudflare Workers]19 WASM --> Embedded[Embedded WAMR]20```2122### Come funziona2324WASM e una **macchina virtuale basata su stack**. Le funzioni inseriscono e rimuovono valori da uno stack di operandi. Il runtime host (V8 in Chrome, SpiderMonkey in Firefox) compila JIT il bytecode WASM in codice macchina nativo, ed e per questo che le prestazioni sono quasi native.2526Caratteristiche principali:2728- **Esecuzione in sandbox**: i moduli WASM possono accedere solo alle risorse che l'host concede esplicitamente. Nessun accesso al filesystem, alla rete o al sistema operativo a meno che non sia permesso. Questo e fondamentalmente diverso dal codice nativo.29- **Memoria lineare**: un singolo `ArrayBuffer` contiguo condiviso tra WASM e l'host. I dati complessi (stringhe, struct) vengono passati scrivendo in memoria e condividendo un puntatore.30- **Tipi limitati**: WASM supporta nativamente solo quattro tipi: `i32`, `i64`, `f32`, `f64`. Tutto il resto (stringhe, array, oggetti) richiede la codifica attraverso la memoria lineare o il Component Model.31- **Portabile**: lo stesso binario `.wasm` gira su qualsiasi piattaforma con un runtime WASM, senza ricompilazione.3233### WASM vs JavaScript3435WASM non sostituisce JavaScript. Lo complementa.3637| Aspetto | JavaScript | WebAssembly |38|---------|-----------|-------------|39| **Parsing** | Parsing + compilazione a runtime | Binario pre-compilato, solo decodifica |40| **Velocita di esecuzione** | Ottimizzato JIT, variabile | Quasi nativo, costante |41| **Avvio** | Veloce per piccoli script | Decodifica veloce, prevedibile |42| **Accesso al DOM** | Diretto | Indiretto (tramite glue JS) |43| **Ideale per** | UI, manipolazione DOM, gestione eventi | Calcolo intensivo sulla CPU |44| **Garbage collection** | Integrato | WasmGC (nuovo), o manuale |4546Usa JavaScript per l'interfaccia utente e il lavoro sul DOM. Usa WASM per il calcolo pesante: elaborazione immagini, codifica video, simulazioni fisiche, crittografia, parsing di dati.4748## WASM 3.0: le novita4950WebAssembly 3.0 e diventato standard W3C nel settembre 2025, standardizzando nove funzionalita che erano in fase di sviluppo da anni.5152| Funzionalita | Cosa abilita |53|--------------|-------------|54| **WasmGC** | Garbage collection nativa in WASM. I linguaggi gestiti (Java, Kotlin, Dart) possono compilare in WASM senza includere il proprio runtime GC. Supportato in Chrome 119+, Firefox 120+, Safari 18.2+. |55| **Exception Handling** | `try`/`catch` nativi in WASM. In precedenza, le eccezioni richiedevano costosi roundtrip verso JavaScript. |56| **Tail Calls** | Abilita la ricorsione efficiente senza stack overflow. Fondamentale per i linguaggi funzionali. |57| **Relaxed SIMD** | Istruzioni vettoriali a 128 bit per l'elaborazione parallela dei dati. Abilita ottimizzazioni specifiche per l'hardware. |58| **Memory64** | Supera il limite di 4GB di memoria lineare. Necessario per l'elaborazione di dati su larga scala. |59| **Multi-memory** | Piu regioni di memoria indipendenti in un singolo modulo. |6061La piu impattante e **WasmGC**. Prima di essa, compilare Java o Kotlin in WASM significava includere un intero garbage collector come parte del binario, gonfiando le dimensioni del file. Ora il GC del browser gestisce la memoria per i moduli WASM, esattamente come fa per JavaScript.6263## WASI: WebAssembly oltre il browser6465WASM nel browser e potente, ma **WASI (WebAssembly System Interface)** e cio che rende WASM un runtime universale. WASI fornisce interfacce standardizzate per le risorse di sistema - file, rete, orologi, numeri casuali - permettendo ai moduli WASM di funzionare al di fuori del browser.6667```mermaid68graph TD69 subgraph "Browser"70 B[WASM Module] --> Web[Web APIs\nDOM, Fetch, Canvas]71 end7273 subgraph "Server / Edge / Embedded"74 S[WASM Module] --> WASI[WASI Interfaces]75 WASI --> FS[wasi:filesystem]76 WASI --> Net[wasi:sockets]77 WASI --> HTTP[wasi:http]78 WASI --> Clock[wasi:clocks]79 WASI --> Rand[wasi:random]80 end81```8283WASI Preview 2 (l'attuale release stabile) definisce queste interfacce:8485- `wasi:filesystem` - operazioni sui file tramite handle di capacita (non i tradizionali file descriptor)86- `wasi:sockets` - networking TCP/UDP87- `wasi:http` - gestione richieste/risposte HTTP88- `wasi:clocks` - orologio di sistema, orologio monotonico89- `wasi:random` - casualita crittografica90- `wasi:cli` - argomenti della riga di comando, variabili d'ambiente, stdio9192Il principio chiave e la **sicurezza basata sulle capacita**: un modulo WASM non puo accedere al filesystem a meno che l'host non conceda esplicitamente un handle a una directory specifica. Questo rende WASI fondamentalmente piu sicuro rispetto all'esecuzione di eseguibili nativi.9394### Il percorso verso WASI 1.09596WASI 0.3.0 (che aggiunge primitive async/concorrenza) e previsto nel 2026, con WASI 1.0 a seguire. L'aggiunta principale e l'async integrato nel linguaggio con I/O streaming a copia zero.9798## Il Component Model99100I moduli WASM di base possono scambiare solo numeri. Il **Component Model** risolve questa limitazione aggiungendo un sistema di tipi ricco e un livello di composabilita sopra WASM.101102### WIT (WebAssembly Interface Types)103104WIT e un linguaggio di definizione delle interfacce che permette ai componenti di dichiarare le proprie importazioni ed esportazioni con tipi ricchi - stringhe, record, liste, varianti, enum - non solo `i32` e `f64`.105106```wit107// calculator.wit108package myorg:calculator@1.0.0;109110interface operations {111 record calculation {112 expression: string,113 result: f64,114 timestamp: u64,115 }116117 add: func(a: f64, b: f64) -> f64;118 multiply: func(a: f64, b: f64) -> f64;119 history: func() -> list<calculation>;120}121122world calculator {123 export operations;124}125```126127Le toolchain come `wit-bindgen` generano binding specifici per il linguaggio a partire dai file WIT. Un componente Rust e un componente Python possono scambiare stringhe, record e liste attraverso contratti WIT senza che nessuna delle due parti conosca il linguaggio di implementazione dell'altra.128129## Costruire il tuo primo modulo WASM con Rust130131Rust ha gli strumenti WASM piu maturi. Costruiamo un esempio pratico: un modulo di elaborazione immagini che gira nel browser.132133### Configurazione134135```bash136# Install the WASM target for Rust137rustup target add wasm32-unknown-unknown138139# Install wasm-pack (builds Rust to WASM + generates JS bindings)140cargo install wasm-pack141142# Create a new library project143cargo new --lib image-processor144cd image-processor145```146147### Configurare Cargo.toml148149```toml150[package]151name = "image-processor"152version = "0.1.0"153edition = "2021"154155[lib]156crate-type = ["cdylib"]157158[dependencies]159wasm-bindgen = "0.2"160```161162### Scrivere il codice Rust163164```rust165// src/lib.rs166use wasm_bindgen::prelude::*;167168/// Convert an image buffer to grayscale.169/// Input: RGBA pixel data as a flat u8 array (4 bytes per pixel).170/// Output: Modified in place for zero-copy performance.171#[wasm_bindgen]172pub fn grayscale(pixels: &mut [u8]) {173 for chunk in pixels.chunks_exact_mut(4) {174 let r = chunk[0] as f32;175 let g = chunk[1] as f32;176 let b = chunk[2] as f32;177 // ITU-R BT.709 luminance coefficients178 let gray = (0.2126 * r + 0.7152 * g + 0.0722 * b) as u8;179 chunk[0] = gray;180 chunk[1] = gray;181 chunk[2] = gray;182 // chunk[3] is alpha, leave unchanged183 }184}185186/// Adjust brightness of an image.187/// factor > 1.0 brightens, < 1.0 darkens.188#[wasm_bindgen]189pub fn adjust_brightness(pixels: &mut [u8], factor: f32) {190 for chunk in pixels.chunks_exact_mut(4) {191 chunk[0] = ((chunk[0] as f32 * factor).min(255.0)) as u8;192 chunk[1] = ((chunk[1] as f32 * factor).min(255.0)) as u8;193 chunk[2] = ((chunk[2] as f32 * factor).min(255.0)) as u8;194 }195}196197/// Invert all colors in the image.198#[wasm_bindgen]199pub fn invert(pixels: &mut [u8]) {200 for chunk in pixels.chunks_exact_mut(4) {201 chunk[0] = 255 - chunk[0];202 chunk[1] = 255 - chunk[1];203 chunk[2] = 255 - chunk[2];204 }205}206207/// Calculate the average brightness of an image (0-255).208#[wasm_bindgen]209pub fn average_brightness(pixels: &[u8]) -> f32 {210 let mut total: f64 = 0.0;211 let pixel_count = pixels.len() / 4;212 for chunk in pixels.chunks_exact(4) {213 let luminance = 0.2126 * chunk[0] as f64214 + 0.7152 * chunk[1] as f64215 + 0.0722 * chunk[2] as f64;216 total += luminance;217 }218 (total / pixel_count as f64) as f32219}220```221222### Build223224```bash225wasm-pack build --target web226```227228Questo produce una directory `pkg/` con:229- `image_processor_bg.wasm` - il binario WASM compilato230- `image_processor.js` - codice glue JavaScript con definizioni TypeScript231- `package.json` - pronto per la pubblicazione su npm232233### Utilizzo in JavaScript234235```html236<!DOCTYPE html>237<html>238<head><title>WASM Image Processor</title></head>239<body>240 <canvas id="canvas" width="800" height="600"></canvas>241 <button onclick="applyGrayscale()">Grayscale</button>242 <button onclick="applyBrightness()">Brighten</button>243 <button onclick="applyInvert()">Invert</button>244245 <script type="module">246 import init, { grayscale, adjust_brightness, invert } from "./pkg/image_processor.js";247248 let ctx;249 let imageData;250251 async function setup() {252 await init();253 const canvas = document.getElementById("canvas");254 ctx = canvas.getContext("2d");255256 // Load an image onto the canvas257 const img = new Image();258 img.onload = () => {259 ctx.drawImage(img, 0, 0);260 imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);261 };262 img.src = "photo.jpg";263 }264265 window.applyGrayscale = () => {266 grayscale(imageData.data);267 ctx.putImageData(imageData, 0, 0);268 };269270 window.applyBrightness = () => {271 adjust_brightness(imageData.data, 1.3);272 ctx.putImageData(imageData, 0, 0);273 };274275 window.applyInvert = () => {276 invert(imageData.data);277 ctx.putImageData(imageData, 0, 0);278 };279280 setup();281 </script>282</body>283</html>284```285286Il punto chiave: `imageData.data` e un `Uint8ClampedArray` supportato da un `ArrayBuffer`. Quando viene passato a WASM, condivide la stessa memoria - nessuna copia. La funzione Rust modifica i pixel direttamente, e il lato JavaScript vede immediatamente le modifiche.287288## Livello piu basso: istanziazione manuale di WASM289290Se non vuoi usare `wasm-bindgen`, puoi istanziare direttamente i moduli WASM:291292```javascript293const response = await fetch("calculator.wasm");294const { instance } = await WebAssembly.instantiateStreaming(response, {295 env: {296 // Functions the WASM module can call297 log_result: (value) => console.log("Result:", value),298 },299});300301// Call exported functions302const { add, multiply } = instance.exports;303console.log(add(5, 3)); // 8304console.log(multiply(4, 7)); // 28305```306307Questo e utile quando si vuole un overhead minimo e non si ha bisogno di interoperabilita avanzata tra tipi.308309## Prestazioni: WASM vs JavaScript310311I benchmark reali mostrano accelerazioni significative per i compiti intensivi sulla CPU:312313| Compito | JavaScript | WASM | Accelerazione |314|---------|-----------|------|---------------|315| Elaborazione immagine 4K | 180ms | 8ms (con SIMD) | 22x |316| Ridimensionamento immagine (4K) | 250ms | 45ms | 5,5x |317| Simulazione fisica (10K entita) | Frame persi | 60fps fluidi | ~10x |318| Parsing JSON (payload grande) | 12ms | 3ms | 4x |319| Hashing crittografico | 45ms | 6ms | 7,5x |320321WASM gira a circa il 95% della velocita del codice nativo. I maggiori guadagni derivano da:322- Prestazioni prevedibili (nessun warmup JIT, nessuna pausa del GC)323- Istruzioni SIMD per l'elaborazione parallela dei dati324- Accesso diretto alla memoria senza interferenza del garbage collector325326Dove WASM NON e piu veloce: manipolazione del DOM, piccoli calcoli, compiti legati all'I/O. JavaScript e gia ottimizzato per questi casi.327328## Casi d'uso in produzione329330### Figma: rendering vettoriale in tempo reale331332Il motore di rendering principale di Figma e C++ compilato in WASM. Ogni forma, gradiente ed effetto viene calcolato in WASM e disegnato su un elemento Canvas. Questo permette a Figma di gestire design complessi con migliaia di livelli a 60fps nel browser - prestazioni impossibili in puro JavaScript.333334### Adobe Photoshop sul web335336Adobe ha portato filtri e strumenti chiave di Photoshop in WASM utilizzando Rust. I loro benchmark mostrano l'elaborazione di immagini 4K in 22ms con WASM SIMD contro 180ms in JavaScript - un miglioramento di 8 volte che rende possibili le anteprime dei filtri in tempo reale.337338### Cloudflare Workers339340Cloudflare esegue moduli WASM in isolati V8 in oltre 330 posizioni edge. I cold start sono di 1-5ms (rispetto ai 100-500ms per il serverless basato su container). A febbraio 2026, hanno distribuito l'inferenza di Llama-3-8b attraverso la loro rete edge utilizzando WASM.341342### Google Meet343344La sfocatura dello sfondo e gli sfondi virtuali in Google Meet utilizzano WASM con SIMD per l'elaborazione video in tempo reale. Il modulo WASM elabora ogni frame video abbastanza velocemente da mantenere un video fluido a 30fps.345346## Supporto browser (2026)347348| Funzionalita | Chrome | Firefox | Safari | Edge |349|--------------|--------|---------|--------|------|350| Core WASM | Completo | Completo | Completo | Completo |351| Threads | Si | Si | Si | Si |352| SIMD (128 bit) | Si | Si | Si | Si |353| WasmGC | 119+ | 120+ | 18.2+ | Si |354| Exception Handling | Si | Si | Si | Si |355| Memory64 | Si | Si | Parziale | Si |356357Tutti i principali browser supportano pienamente WASM. Le funzionalita piu recenti (WasmGC, Exception Handling) hanno raggiunto un'ampia disponibilita.358359## Riferimento degli strumenti360361| Strumento | Scopo | Installazione |362|-----------|-------|---------------|363| **wasm-pack** | Compilare Rust in WASM, generare pacchetti npm | `cargo install wasm-pack` |364| **wasm-bindgen** | Binding di interoperabilita Rust/JS (usato da wasm-pack) | Dipendenza nel Cargo.toml |365| **wasm-opt** | Ottimizzazione delle dimensioni del binario (riduzione del 50%+) | Parte di Binaryen: `brew install binaryen` |366| **wit-bindgen** | Generare binding dai file WIT | `cargo install wit-bindgen-cli` |367| **Wasmtime** | Runtime WASM lato server (implementazione di riferimento WASI) | `brew install wasmtime` |368| **Wasmer** | Runtime WASM alternativo con supporto WASI | `curl https://get.wasmer.io -sSfL \| sh` |369| **wasm-feature-detect** | Rilevamento delle funzionalita del browser a runtime | `npm install wasm-feature-detect` |370371### Ottimizzare le dimensioni del binario372373I binari WASM possono essere grandi. Ecco come ridurli:374375```toml376# Cargo.toml377[profile.release]378opt-level = "z" # Optimize for size379lto = true # Link-time optimization380codegen-units = 1 # Better optimization, slower compile381strip = true # Strip debug symbols382```383384```bash385# Build in release mode386wasm-pack build --release --target web387388# Further optimize with wasm-opt389wasm-opt -Oz pkg/image_processor_bg.wasm -o pkg/image_processor_bg.wasm390```391392Un tipico modulo WASM in Rust passa da 500KB a meno di 50KB con queste ottimizzazioni.393394## Percorso per iniziare395396```mermaid397flowchart TD398 A[Week 1: Basics] --> B[Week 2: Real Project]399 B --> C[Week 3: WASI and Server-side]400 C --> D[Month 2+: Production]401402 A --> A1[Install Rust + wasm-pack]403 A --> A2[Build hello-world WASM module]404 A --> A3[Call WASM functions from JavaScript]405406 B --> B1[Build image processor or game physics]407 B --> B2[Use wasm-bindgen for rich types]408 B --> B3[Benchmark against pure JS]409410 C --> C1[Run WASM with Wasmtime]411 C --> C2[Explore WASI interfaces]412 C --> C3[Try Component Model with WIT]413414 D --> D1[Optimize binary size]415 D --> D2[Use SIMD for parallelism]416 D --> D3[Deploy to Cloudflare Workers or browser]417```418419## Conclusione420421WebAssembly non e piu sperimentale. E una tecnologia di produzione utilizzata da alcune delle applicazioni piu impegnative del web. Prestazioni quasi native, sicurezza in sandbox e portabilita universale - nessun altro target di compilazione ti offre tutte e tre queste caratteristiche.422423Non devi riscrivere l'intera applicazione in WASM. Inizia con una singola funzione intensiva sulla CPU - un filtro per immagini, un parser di dati, un calcolo fisico - compilala in WASM e chiamala da JavaScript. Misura la differenza. Poi decidi dove altro WASM puo essere d'aiuto.424425Gli strumenti sono maturi, il supporto dei browser e universale e l'ecosistema sta crescendo. Se scrivi in Rust, sei gia a un comando di distanza dal browser.426427> **Checklist per iniziare:**428>429> - [x] Rust e wasm-pack installati430> - [x] Primo modulo WASM compilato e funzionante nel browser431> - [x] Interoperabilita JavaScript funzionante (chiamare WASM da JS)432> - [x] Build di rilascio con ottimizzazioni delle dimensioni applicate433> - [x] Prestazioni confrontate con l'equivalente in puro JavaScript434> - [x] WASI esplorato con Wasmtime per i casi d'uso lato server435
:WebAssembly per sviluppatori web: da zero alla produzionelines 1-435 (END) — press q to close