Per oltre vent'anni JavaScript è stato il linguaggio incontrastato del web, ma l'ambiente di esecuzione del browser non è più monolingue. WebAssembly è diventato in silenzio il secondo runtime di ogni browser moderno e abilita capacità che JavaScript da solo non può offrire in modo efficiente. Editor di immagini, codec video, motori di database, renderer 3D, runtime di linguaggi: tutto questo gira oggi dentro schede del browser, compilato in un formato binario di basso livello che raggiunge velocità quasi native.
Che cos'è WebAssembly e perché conta
WebAssembly è un formato binario di istruzioni di basso livello eseguito da una macchina virtuale a stack. È stato progettato come bersaglio di compilazione portabile per i linguaggi di programmazione, per consentire il rilascio sul web di applicazioni client e server. I quattro produttori di browser — Google, Mozilla, Apple e Microsoft — hanno collaborato alla progettazione, e nel 2019 è diventato uno standard del W3C. Tutti i browser principali lo supportano dal 2017.
Ma WebAssembly non sostituisce JavaScript: lo completa. JavaScript resta il linguaggio della manipolazione del DOM, della gestione degli eventi e della logica di interfaccia. WebAssembly si occupa del lavoro a forte carico computazionale per cui JavaScript non è mai stato pensato. I due runtime convivono nella stessa scheda: i moduli importano funzioni JavaScript e JavaScript invoca gli export Wasm attraverso un'API ben definita.
WebAssembly non punta a sostituire JavaScript. Punta a risolvere i problemi che JavaScript non può risolvere in modo efficiente. La piattaforma web ne esce più forte, perché gli sviluppatori possono scegliere lo strumento giusto per ogni compito all'interno della stessa applicazione.
Fondamenti: formato binario e memoria lineare
I moduli WebAssembly usano un formato binario (file .wasm) progettato per un'analisi rapida e una trasmissione leggera. Il formato è compatto: un modulo tipico è nettamente più piccolo del JavaScript equivalente, anche dopo la minificazione. Codifica tipi, funzioni, import, export, dichiarazioni di memoria e istruzioni in una rappresentazione densa che i browser possono validare e compilare in un'unica passata lineare.
Ogni modulo WebAssembly opera su una macchina a stack concettuale. Le istruzioni impilano valori su uno stack di valutazione e li estraggono per eseguire operazioni. I tipi di valore supportati sono i32, i64, f32 e f64: interi e numeri in virgola mobile a 32 e 64 bit. A livello Wasm non esistono stringhe, oggetti, array o altri tipi di alto livello. Ogni struttura dati complessa va rappresentata in memoria lineare come byte grezzi.
La memoria lineare è il concetto più importante di WebAssembly. Ogni modulo può dichiarare uno o più blocchi di memoria contigua e ridimensionabile. Questa memoria è un array piatto di byte che il modulo legge e scrive con istruzioni di load e store. L'host — il runtime JavaScript o quello Wasm — controlla la dimensione iniziale e quella massima e può farla crescere richiedendo pagine aggiuntive da 65.536 byte ciascuna. Dal lato host questa memoria è accessibile come ArrayBuffer, il che significa che JavaScript legge e scrive esattamente la memoria usata dal modulo.
È questo modello a memoria condivisa a rendere WebAssembly efficiente. Host e modulo si scambiano dati senza serializzazione né copie: scrivono semplicemente sullo stesso buffer. Quando una funzione Rust restituisce una stringa a JavaScript, scrive i byte in memoria lineare e restituisce un puntatore (uno scostamento intero) e una lunghezza. JavaScript legge quei byte direttamente dall'ArrayBuffer. Nessun parsing JSON, nessuno scambio di messaggi, nessun costo oltre quello della chiamata stessa.
Struttura del modulo e validazione
Un modulo WebAssembly è composto da sezioni: quella dei tipi definisce le firme delle funzioni, quella delle funzioni le dichiara, quella di codice contiene il bytecode, quella di memoria definisce la memoria lineare e quella degli export mette funzioni e memoria a disposizione dell'host. Prima di qualunque esecuzione, il browser valida il modulo dal punto di vista strutturale e impone la sicurezza dei tipi. La validazione garantisce che tutti gli operandi corrispondano ai tipi attesi, che tutte le chiamate facciano riferimento a firme valide e che ogni accesso alla memoria resti entro i limiti dichiarati. Richiede millisecondi e assicura che un modulo malformato non possa sfruttare il runtime.
Il modello di sicurezza è esplicito e ristretto. Un modulo WebAssembly non può accedere al DOM, fare richieste di rete, leggere file o interagire con il sistema, a meno che l'host non conceda esplicitamente tali capacità tramite funzioni importate. Il modulo opera in una sandbox senza accesso a nulla al di fuori della propria memoria lineare e della tabella di funzioni importate. Ciò rende sicura l'esecuzione di moduli provenienti da fonti non fidate, proprietà decisiva sia nel browser sia sul server.
Compilare verso Wasm: Rust, C, Go e Zig a confronto
La qualità della compilazione verso WebAssembly varia molto da linguaggio a linguaggio. Alcuni producono moduli compatti ed efficienti, con pochissimo sovraccarico. Altri richiedono un runtime che aggiunge megabyte al binario. La scelta del linguaggio sorgente dipende dai requisiti di prestazione, dall'esperienza del team e dalla complessità dell'integrazione necessaria.
Rust: il riferimento per Wasm
Rust offre il miglior supporto a WebAssembly fra tutti i linguaggi. La toolchain wasm-pack gestisce senza attriti compilazione, ottimizzazione e generazione dei binding JavaScript. Rust produce binari piccoli perché non ha garbage collector né un runtime pesante, e il suo modello di ownership si mappa naturalmente sulla gestione della memoria lineare. Un modulo tipico con poche funzioni esportate pesa fra 10 KB e 50 KB dopo LTO e ottimizzazione, un valore competitivo con il Wasm scritto a mano.
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
extern "C" {
fn alert(s: &str);
}
#[wasm_bindgen]
pub fn fibonacci(n: u32) -> u32 {
match n {
0 => 0,
1 => 1,
_ => fibonacci(n - 1) + fibonacci(n - 2),
}
}
#[wasm_bindgen]
pub fn greet(name: &str) -> String {
format!("Hello, {}! Wasm says hello.", name)
}Il crate wasm_bindgen genera il codice di collegamento JavaScript che gestisce automaticamente la danza della memoria lineare. Chiamare fibonacci da JavaScript è indistinguibile da qualunque altra chiamata. Dietro le quinte, wasm_bindgen traduce i parametri stringa in coppie puntatore-lunghezza, invoca la funzione Wasm e riconverte il risultato in una stringa JavaScript. Questo strato di astrazione costa pochissimo e rende praticabile ogni giorno l'integrazione Rust-Wasm.
C e C++ tramite Emscripten
Emscripten è la toolchain originale per Wasm. Compila codice C e C++ usando LLVM come backend e fornisce un ampio strato di compatibilità POSIX che consente di portare sul web applicazioni native esistenti con modifiche minime al sorgente. Include un filesystem virtuale, la traduzione da OpenGL a WebGL, l'emulazione di pthread e un runtime JavaScript che gestisce il ciclo di vita del modulo.
Go con il backend Wasm ufficiale
Go supporta WebAssembly dalla versione 1.11 e il supporto migliora a ogni rilascio. Compilare un programma Go verso Wasm è semplice: si impostano GOOS=js GOARCH=wasm e si esegue go build. Il supporto di Go, però, ha limiti evidenti rispetto a Rust. Go include il proprio runtime (scheduler delle goroutine, garbage collector, stack dei defer) in ogni binario, per cui un modulo minimo parte da circa 2 MB. È accettabile lato server, dove la dimensione conta meno, ma proibitivo nel browser, dove tempi di download e di parsing sono critici.
Zig: il nuovo sfidante
Zig si propone come sostituto moderno di C con supporto di prima classe a WebAssembly. Il suo compilatore può puntare direttamente a Wasm senza involucri come Emscripten. Produce moduli competitivi con Rust per dimensione e prestazioni, e la sua funzionalità comptime consente una metaprogrammazione capace di eliminare del tutto il sovraccarico a runtime. Zig non porta con sé alcun runtime nascosto — niente garbage collector, niente allocatore, niente codice di avvio — a meno che non lo si colleghi esplicitamente.
- Rust produce i binari Wasm più piccoli (10-50 KB per moduli tipici) e ha il miglior ecosistema di strumenti con wasm-pack e wasm-bindgen.
- C e C++ tramite Emscripten sono la scelta migliore per portare codebase native esistenti verso Wasm: massima compatibilità, ma binari più grandi.
- Go si compila facilmente verso Wasm ma genera binari voluminosi (oltre 2 MB) a causa del runtime incluso, il che lo rende più adatto al Wasm lato server.
- Zig produce moduli compatti senza sovraccarico di runtime ed è ideale per usi Wasm minimali ed embedded.
Usare Wasm nel browser
Caricare ed eseguire un modulo WebAssembly nel browser segue un'API standard, identica su tutti i browser moderni. L'API JavaScript espone nel namespace WebAssembly le funzioni compile, instantiate e instantiateStreaming. La variante in streaming è preferibile perché inizia a compilare mentre i byte vengono scaricati, sovrapponendo I/O di rete e compilazione.
async function loadWasm(url: string) {
const response = await fetch(url);
const results = await WebAssembly.instantiateStreaming(response);
return results.instance.exports;
}
async function main() {
const wasm = await loadWasm("/fibonacci.wasm");
console.log(wasm.fibonacci(40));
}
main().catch(console.error);instantiateStreaming restituisce un oggetto con la proprietà instance (l'istanza compilata del modulo) e un oggetto exports con tutte le funzioni e la memoria dichiarate come export. È possibile passare anche un oggetto imports come secondo argomento, che dà al modulo accesso alle funzioni e ai valori JavaScript che si aspettava al momento della compilazione.
In produzione si tende a precompilare il modulo durante la fase di build o a usare un plugin del bundler. Webpack 5 supporta nativamente gli import Wasm e Vite ha un supporto sperimentale. Questi bundler gestiscono automaticamente download, istanziazione e ciclo di vita, consentendo di importare moduli Wasm come fossero moduli JavaScript. Con wasm-pack lo schema di import è import init from './pkg/fibonacci.js', che restituisce una funzione di inizializzazione basata su promise incaricata di tutto il codice di collegamento.
Un aspetto critico nel browser è la prima compilazione. I moduli vengono compilati dal formato binario a codice nativo al primo caricamento. Per moduli piccoli si parla di pochi millisecondi. Per moduli grandi — oltre i 10 MB — possono servire diverse centinaia di millisecondi, con blocco del thread principale. La soluzione è usare WebAssembly.compileStreaming in un Web Worker: la compilazione avviene fuori dal thread principale e restituisce un oggetto modulo compilato che il thread principale può istanziare all'istante. È uno schema indispensabile per applicazioni che caricano moduli grandi.
WASI e Wasm lato server
WebAssembly nasce pensato esclusivamente per il browser, ma il suo modello di sicurezza e le sue caratteristiche prestazionali lo rendono altrettanto interessante lato server. La difficoltà è che il browser fornisce API host specifiche — DOM, fetch, WebSocket — assenti negli ambienti server. La WebAssembly System Interface risolve il problema definendo un insieme standard di chiamate di sistema in stile POSIX utilizzabili fuori dal browser.
WASI offre astrazioni per I/O su file, rete, accesso all'orologio, generazione di numeri casuali, variabili d'ambiente e argomenti da riga di comando. Un modulo compilato con supporto WASI può leggere file, aprire socket di rete e dialogare con il sistema operativo attraverso un'interfaccia normalizzata che funziona su qualunque runtime conforme. È questa la base per eseguire Wasm come applicazione server.
Lo standard WASI evolve per istantanee successive. WASI preview 1 è la base stabile supportata oggi dalla maggior parte delle toolchain. WASI preview 2 introduce un impianto allineato al modello a componenti, con sicurezza basata su capacità, dove ogni modulo dichiara esplicitamente quali risorse di sistema gli servono. Preview 2 è un progresso architetturale rilevante perché rende possibili permessi a grana fine: un modulo che deve leggere solo un file specifico non può raggiungere nessun altro file del sistema.
WASI trasforma WebAssembly da tecnologia del browser in un runtime isolato e universale. Lo stesso modulo che gira in una scheda del browser può girare in un runtime Wasm lato server, in una funzione serverless o su un nodo di edge, senza modifiche. «Scrivi una volta, esegui ovunque» assume un altro significato quando quell'ovunque comprende ambienti che JavaScript non raggiunge.
Runtime Wasm e distribuzione
Eseguire WebAssembly fuori dal browser richiede un runtime lato server. Ne esistono diversi maturi, con filosofie di progetto e casi d'uso differenti. I tre più importanti sono Wasmtime, Wasmer e WAMR (WebAssembly Micro Runtime) per i sistemi embedded.
Wasmtime
Wasmtime è un runtime autonomo sviluppato dalla Bytecode Alliance, la stessa organizzazione che porta avanti lo standard WASI. È scritto in Rust, compila i moduli con Cranelift (un generatore di codice progettato appositamente per Wasm) e offre API in Rust, C, Python e altri linguaggi. È il runtime più diffuso per il Wasm lato server e sta dietro a Cloudflare Workers, Fastly Compute@Edge e ad altre piattaforme di edge computing.
use wasmtime::*;
fn main() -> Result<()> {
let engine = Engine::default();
let module = Module::from_file(&engine, "hello.wasm")?;
let mut store = Store::new(&engine, ());
let instance = Instance::new(&mut store, &module, &[])?;
let hello = instance
.get_typed_func::<(), ()>(&mut store, "hello")?;
hello.call(&mut store, ())?;
Ok(())
}L'API di integrazione di Wasmtime è pulita e idiomatica. Si crea un Engine (l'ambiente di compilazione), si carica un Module da file o da byte, si crea uno Store (il contesto di esecuzione che contiene la memoria lineare) e si istanzia il modulo per accedere alle funzioni esportate. Il runtime gestisce da sé memoria, trap e inoltro delle chiamate di sistema WASI.
Wasmer
Wasmer è un altro runtime molto usato, che supporta più backend di compilazione: Cranelift, LLVM e Singlepass (compilazione JIT rapida con ottimizzazione minima). Offre SDK per Rust, C, C++, Python, Go, PHP, Ruby, Java e altri, risultando accessibile da quasi ogni ambiente di programmazione. Mette inoltre a disposizione un registro di pacchetti (WAPM) per distribuire moduli Wasm, sul modello di npm.
La differenza chiave è che Wasmer punta sull'esperienza dello sviluppatore e sulla facilità di integrazione, mentre Wasmtime punta sulla conformità allo standard e sulla sicurezza. Entrambi sono ottime scelte; la selezione dipende da ciò a cui si dà più valore: l'ampiezza dell'ecosistema (Wasmer) oppure la stretta conformità alle specifiche e la storia in produzione (Wasmtime).
- Wasmtime: il migliore per Wasm lato server in produzione, conformità WASI rigorosa, compilatore JIT Cranelift, usato da Cloudflare e Fastly.
- Wasmer: il migliore per integrare Wasm in applicazioni non scritte in Rust, supporta la compilazione LLVM per velocità quasi native e dispone dell'ecosistema di pacchetti WAPM.
- WAMR: il migliore per IoT e dispositivi embedded, impronta minima, modalità interprete e JIT, con lo strumento a riga di comando iwasm.
Prestazioni: quando conviene Wasm
Il vantaggio prestazionale di WebAssembly su JavaScript dipende dal carico di lavoro. Per operazioni vincolate alla CPU e a forte contenuto numerico, Wasm gira di norma da 1,5 a 3 volte più veloce. Per operazioni intensive in memoria, come l'elaborazione di immagini o la compressione, il vantaggio può essere maggiore perché Wasm controlla direttamente la disposizione della memoria e gli schemi di allocazione. Per carichi dominati da I/O o dal DOM, Wasm non offre vantaggi e può anzi aggiungere costo a causa del ponte fra modulo e host JavaScript.
Conta anche il modello di compilazione. JavaScript usa la compilazione JIT: il codice parte subito e i percorsi caldi vengono ottimizzati col tempo. Wasm viene compilato in anticipo o al caricamento del modulo, perciò raggiunge subito le prestazioni massime: non c'è fase di riscaldamento. Per funzioni di breve durata o esecuzioni singole, ciò elimina il ritardo di riscaldamento del JIT che può rendere JavaScript più lento alla prima invocazione.
È sulla prevedibilità che Wasm eccelle davvero. L'ottimizzazione JIT di JavaScript non è deterministica: la stessa funzione può essere ottimizzata o deottimizzata a seconda dei tipi ricevuti, del numero di chiamate e dello stato delle euristiche del compilatore. L'esecuzione Wasm è invece deterministica. Ogni istruzione ha un costo fisso. Niente pause di garbage collection, niente confusione di tipi, niente abbandono delle ottimizzazioni. Per questo Wasm è la scelta giusta quando la costanza della latenza conta più del picco teorico di throughput: elaborazione audio, simulazione fisica, calcoli finanziari.
- Wasm vince per: elaborazione di immagini e video, sintesi e analisi audio, compressione e decompressione di dati, operazioni crittografiche, motori di gioco, simulazioni fisiche, esecuzione di query di database.
- JavaScript vince per: manipolazione del DOM, gestione degli eventi, orchestrazione delle richieste di rete, rendering di interfacce con framework, elaborazione di stringhe e testo, utilità piccole o chiamate di rado.
- Il confine si sposta: man mano che Wasm accede alle API web tramite WASI e il modello a componenti, altri carichi migrano verso Wasm, ma JavaScript resta lo strato di interfaccia principale.
Il modello a componenti e il futuro di Wasm
Il modello a componenti di WebAssembly è l'evoluzione più significativa dal rilascio iniziale. Affronta il limite di fondo del primo Wasm: moduli isolati, senza un modo standard per interfacciarsi fra loro. Il modello a componenti introduce un sistema di interfacce di alto livello e indipendente dal linguaggio, che permette di comporre i moduli come mattoncini.
Nel modello attuale un modulo esporta funzioni che accettano e restituiscono solo interi e numeri in virgola mobile. Se un modulo deve passare una stringa, un array o una struttura complessa a un altro, i due devono accordarsi su una convenzione di disposizione della memoria: condividere una regione di memoria lineare e coordinare allocazione e deallocazione. È fragile e specifico del linguaggio. Il modello a componenti lo risolve definendo un sistema normalizzato di tipi di interfaccia che gestisce stringhe, record, varianti, liste e strutture annidate attraverso i confini fra moduli.
I tipi di interfaccia descrivono in modo indipendente dal linguaggio i dati che scorrono fra i componenti. Un componente può esportare una funzione che riceve una stringa e restituisce un record con due campi interi, e qualunque altro componente — scritto in Rust, C o Go — può chiamarla senza sapere nulla della disposizione interna della memoria dell'altro. Il runtime genera automaticamente la logica di adattamento e traduce fra la rappresentazione del chiamante e quella del chiamato.
Casi reali
WebAssembly non è una tecnologia teorica. Alimenta alcune delle applicazioni web più esigenti oggi in produzione, e la sua adozione accelera man mano che gli strumenti maturano e i vantaggi prestazionali diventano innegabili.
Figma: il pioniere di Wasm
Figma è il caso di successo più noto. Il suo motore di rendering è scritto in C++ e compilato verso Wasm con Emscripten. Figma compila l'intera codebase C++ — compresa la libreria grafica Skia, il compositore di testo HarfBuzz e il proprio motore di layout — in un modulo Wasm. Lo strato JavaScript gestisce eventi di input e DOM, mentre Wasm si occupa di tutto il rendering, del rilevamento dei clic e dei calcoli di layout. Il risultato è uno strumento di design che gira in una scheda del browser con prestazioni paragonabili a quelle di un'applicazione desktop nativa.
SQLite: un database nel browser
SQLite è probabilmente il modulo Wasm più diffuso al mondo. Il progetto pubblica una build ufficiale che esegue il motore completo nel browser. Gli utenti possono interrogare un database interamente lato client, senza alcuna componente server. La build è prodotta con Emscripten e include il supporto a un filesystem virtuale per conservare i database in IndexedDB.
Le implicazioni sono notevoli. Le applicazioni che necessitano di capacità di interrogazione lato client — strumenti di analisi, cruscotti di reportistica, quaderni di calcolo scientifico — possono usare SQLite in Wasm per eseguire aggregazioni complesse, join e funzioni finestra direttamente nel browser, senza inviare dati a un server. Librerie come sql.js e better-sqlite3-wasm avvolgono il modulo in API JavaScript pulite e lo rendono comodo quanto qualsiasi pacchetto npm.
Google Earth: Wasm per il rendering 3D
Google Earth per browser è stato ricostruito con Wasm per le pipeline di elaborazione del terreno 3D e di decompressione dei dati. Mentre l'utente naviga, il modulo riceve dati binari compressi, li decomprime con algoritmi C++ ottimizzati e compilati verso Wasm, trasforma la geometria in mesh renderizzabili e passa il risultato a WebGL, il tutto entro il budget di un singolo fotogramma e senza alcun costo di copia dei dati.
- Figma usa Wasm per il suo motore di rendering C++ e raggiunge prestazioni di classe nativa nell'editing di grafica vettoriale nel browser.
- SQLite pubblica una build Wasm ufficiale che esegue il motore completo lato client, abilitando query offline senza server.
- Google Earth si affida a Wasm per la decompressione in tempo reale e l'elaborazione geometrica di dati geospaziali in streaming a 60 fotogrammi al secondo.
- Adobe usa Wasm in Photoshop per il web (tramite codice C++ compilato con Emscripten) per i filtri di immagine e le conversioni di spazio colore.
- Zoom usa Wasm nel client web per la decodifica video e la sfocatura dello sfondo.
Wasm sull'edge e in serverless
Le piattaforme serverless hanno adottato WebAssembly come runtime per l'edge computing grazie al suo vantaggio sull'avvio a freddo rispetto ai container. Un modulo Wasm parte in microsecondi — non in millisecondi — perché non c'è un sistema operativo da avviare, nessun processo da duplicare, nessun runtime da inizializzare. Dove la latenza di avvio a freddo incide direttamente sull'esperienza d'uso, è un cambio di natura.
Cloudflare Workers è stata la prima grande piattaforma ad adottare Wasm. I Workers girano in isolati V8 capaci di eseguire sia JavaScript sia moduli Wasm. Un Worker che affida la logica di calcolo a un modulo può iniziare a servire richieste in meno di 5 millisecondi dall'avvio a freddo. L'ambiente offre un insieme limitato di API basate sulla specifica Service Worker — fetch, Cache, archiviazione KV e Durable Objects — e i moduli compilati con supporto WASI possono usarle attraverso il meccanismo di import dell'host.
Compute@Edge di Fastly usa Wasmtime come runtime principale e richiede che ogni calcolo sia compilato verso Wasm. Gli sviluppatori scrivono la logica di edge in Rust, Go o JavaScript (che Fastly compila in anticipo verso Wasm) e il modulo risultante gira sui nodi di edge di Fastly. Questo modello offre un forte isolamento di sicurezza — ogni richiesta gira in un'istanza nuova, senza stato condiviso — insieme alla velocità di avvio che rende praticabile l'edge computing.
L'ecosistema Wasm sull'edge è ancora giovane ma cresce in fretta. Piattaforme come Fermyon Spin e Deislabs offrono framework pensati specificamente per costruire applicazioni serverless in Wasm. Nascondono i dettagli del runtime WASI e forniscono schemi familiari — gestori HTTP, archiviazione chiave-valore, attività pianificate — eseguendo però tutto tramite Wasm. La promessa è scrivere la logica di business una sola volta, in qualunque linguaggio che compili verso Wasm, e distribuirla senza modifiche su qualsiasi piattaforma compatibile con WASI.
Come iniziare oggi con Wasm
Il modo migliore per iniziare dipende dall'obiettivo. Per usare Wasm nel browser, la via più rapida è Rust con wasm-pack. Si installa Rust, si aggiunge il target wasm32-unknown-unknown e si crea un progetto con wasm-pack new. Il progetto generato contiene un esempio funzionante con una funzione Wasm richiamabile da JavaScript, uno script di build che produce un pacchetto compatibile con npm e un banco di prova che esegue il modulo in un browser senza interfaccia.
Per esplorare il Wasm lato server si parte da Wasmtime e dal suo strumento a riga di comando. Si installa wasmtime, si compila un qualsiasi programma C o Rust con supporto WASI e lo si esegue con wasmtime programma.wasm. Si vedrà che un programma a riga di comando compilato verso Wasm si comporta come un binario nativo: legge dallo standard input, scrive sullo standard output, accede ai file e termina con un codice di stato. L'esperienza è sorprendentemente fluida.
Per sperimentare su edge e serverless, Cloudflare Workers offre un piano gratuito con supporto a Wasm. Si scrive una funzione in Rust, la si compila verso Wasm e la si distribuisce sulla rete globale di Cloudflare. Si vedranno tempi di risposta sotto i 10 millisecondi dalla maggior parte delle località e si toccherà con mano come Wasm elimini l'avvio a freddo dalle preoccupazioni.
Il primo passo più pratico con Wasm non è riscrivere tutta l'applicazione. Trovate una funzione costosa dal punto di vista computazionale — un filtro, una trasformazione, una validazione —, riscrivetela in Rust, compilatela verso Wasm e integratela nella codebase esistente. Misurate la differenza. Quando vedrete un guadagno di tre volte per cinquanta righe di Wasm, capirete perché questa tecnologia conta.
Il panorama degli strumenti migliora rapidamente. wasm-pack, cargo-generate e wasm-tools offrono un flusso di sviluppo maturo. La toolchain Binaryen mette a disposizione wasm-opt per ottimizzare i moduli e ridurne la dimensione del 20-30 per cento. Wasmtime e Wasmer continuano a colmare il divario con l'esecuzione nativa. E il modello a componenti renderà presto i moduli interoperabili in modi impossibili agli esordi di Wasm.
WebAssembly non sostituisce il web che conosciamo: arricchisce la piattaforma, con un secondo runtime che fa ciò che JavaScript non può. La prossima volta che affronterete un problema di prestazioni in cui vi sembra di combattere contro la natura dinamica di JavaScript, chiedetevi se la parte a forte carico computazionale possa essere estratta in un modulo Wasm. Gli strumenti sono pronti per la produzione, il guadagno è reale, e il futuro di Wasm — con il modello a componenti, WASI preview 2 e un supporto più ampio ai linguaggi — non fa che migliorare.
La piattaforma web è nata per essere estensibile. WebAssembly ne è l'estensione più importante da un decennio. Comprenderla non è facoltativo per chi vuole costruire applicazioni che spingono i limiti di ciò che il web sa fare.