La prima volta che la maggior parte degli sviluppatori sente parlare di WebAssembly, la spiegazione è confezionata in modo riduzionista: viene utilizzato per eseguire codice C o Rust all'interno del browser con prestazioni vicine a quelle native. È corretto ed è solo la punta dell'iceberg.
Quello che è successo negli ultimi anni è stato più interessante del pesante gioco sul web. WebAssembly, o Wasm, è diventato un formato di bytecode portatile che viene eseguito all'esterno del browser, sui server, all'edge, all'interno dei database, come sistema di plug-in e come livello di isolamento per codice di terze parti.
Quando smetti di vedere Wasm come una funzionalità frontend e inizi a vederlo come un obiettivo di compilazione universale, la conversazione cambia. Smette di essere un dettaglio di implementazione e diventa una decisione architetturale.
Cos'è veramente WebAssembly
Wasm è un formato di istruzioni binarie per una macchina virtuale stack. Compila il codice da un linguaggio di alto livello (Rust, C, C++, Go e sempre più altri) in questo formato e qualsiasi runtime compatibile può eseguirlo.
La proprietà che lo rende prezioso non è solo la velocità. È la combinazione di tre cose: reale portabilità tra ambienti, isolamento per impostazione predefinita e dimensioni compatte degli artefatti.
Portabilità significa che lo stesso binario viene eseguito nel browser, su un server Linux, in un contenitore minimalista e su un dispositivo periferico, senza ricompilare per ciascun target. Il runtime astrae la piattaforma.
Isolamento significa che il modulo Wasm funziona in una scatola chiusa. Non ha accesso al file system, alla rete o alla memoria del processo host a meno che l'host non conceda esplicitamente questo accesso. Il modello è negato per impostazione predefinita, l'opposto di una libreria nativa che eredita tutti i privilegi del processo.
Le dimensioni compatte contano perché un modulo Wasm è piccolo e si avvia velocemente. Non sono presenti immagini del contenitore da centinaia di megabyte o lunghi processi di avvio.
Perché ha smesso di essere una cosa del browser
La svolta concettuale arrivò con un'interfaccia chiamata WASI, System Interface for WebAssembly. Definisce come un modulo Wasm comunica con il mondo esterno (file, orologio, rete, variabili d'ambiente) in modo standardizzato e al di fuori del browser.
Prima di WASI, Wasm dipendeva dalle API del browser per tutto. Con esso arriva un contratto neutrale rispetto alla piattaforma. Un runtime sul server implementa WASI e improvvisamente lo stesso binario che verrebbe eseguito nel browser viene eseguito su un host server con accesso controllato alle risorse.
Ciò sblocca l’idea di Wasm come obiettivo universale. Il browser diventa solo uno degli ambienti possibili, non l'unico.
I runtime maturi apparsi in questo ambito (Wasmtime, WasmEdge, Wasmer, tra gli altri) trattano Wasm come un'unità di esecuzione di prima classe sul server. Caricano il modulo, applicano limiti di risorse, garantiscono funzionalità specifiche ed eseguono, il tutto con un sovraccarico molto inferiore rispetto al caricamento di un contenitore o di una macchina virtuale tradizionale.
Dove cambia l'architettura
Pensa al problema di eseguire codice che non hai scritto tu e di cui non ti fidi completamente. Plugin di terze parti, funzioni inviate dai clienti, estensioni di una piattaforma, regole personalizzate definite da un utente.
La risposta tradizionale a questo problema è costosa: contenitori, sandbox del sistema operativo, processi isolati, macchine virtuali leggere. Tutto questo funziona, ma ha un impatto negativo sui tempi di avvio, sul consumo di memoria e sulla complessità operativa.
Wasm offre un'alternativa molto più dettagliata. Esegui codice non attendibile all'interno di un modulo isolato, nello stesso processo, a partire da microsecondi e con un limite di sicurezza definito dal modello di macchina virtuale stesso.
Si aprono così tre fronti che meritano l’attenzione di chi progetta sistemi. Il primo è l'edge: le funzioni che devono essere avviate istantaneamente e scalabili in molte posizioni geografiche traggono vantaggio dalle dimensioni e dalla velocità di avvio di Wasm. Il secondo è l'estensibilità del prodotto: puoi consentire ai clienti di scrivere logica personalizzata ed eseguirla in sicurezza all'interno della tua piattaforma. Il terzo è l'esecuzione multi-runtime: lo stesso componente viene eseguito in ambienti diversi senza riscrittura.
Ognuno di questi fronti merita una propria analisi approfondita, ed esplorerò il caso di edge in dettaglio e il caso di plugin e sandbox in altri testi.
Cosa non è Wasm
Vale la pena calibrare le aspettative, perché l’entusiasmo tende a prevalere sulla realtà tecnica.
Wasm non sostituisce l'intero backend. È un'unità di esecuzione, non un framework applicativo. Hai ancora bisogno di orchestrazione, persistenza, osservabilità e tutto il resto dell'apparato.
Wasm non è magicamente più veloce del codice nativo. In molti casi funziona in modo simile a quello nativo, ma presenta un sovraccarico di traduzione e limiti del modello di macchina stack. Il vero vantaggio in termini di prestazioni, rispetto ai contenitori, è più nel tempo di avvio e nella densità che nel throughput grezzo.
Wasm ha ancora dei limiti sull’integrazione. Accesso alle risorse di sistema, threading, supporto completo di ogni linguaggio per il target Wasm, strumenti di debug: tutto questo si è evoluto, ma non è allo stesso livello di maturità di un ecosistema nativo consolidato. Vale la pena conoscere i limiti del modello a componenti prima di scommettere in grande.
E Wasm non rinuncia al lavoro di sicurezza. L'isolamento per impostazione predefinita è una base solida, ma il modo in cui si concedono funzionalità, si limitano le risorse e si controlla ciò che fa il modulo rimane di responsabilità dell'architetto.
##Come pensare all'adozione
Il modo produttivo per valutare Wasm non è chiedersi se sia migliore di un’altra tecnologia in astratto. Significa identificare dove la combinazione specifica di portabilità, isolamento e avvio rapido risolve un problema che le tue alternative risolvono scarsamente.
Se devi eseguire codice non attendibile con granularità fine, Wasm è un ottimo candidato. Se hai bisogno dello stesso artefatto in esecuzione in ambienti eterogenei senza ricompilare, Wasm è in grado di farlo. Se hai bisogno di funzioni scalabili su molti punti con una latenza di avvio minima, Wasm brilla.
Se nel tuo sistema non esiste nessuna di queste pressioni, probabilmente non c’è urgenza. Adottare Wasm perché è interessante, senza un dolore concreto che allevia, è il tipo di decisione che genera debito senza ritorno.
La lettura strategica è semplice: Wasm è un livello di esecuzione portatile e sicuro, e livelli come questo sono raramente protagonisti. Sono infrastrutture che sbloccano casi d'uso. Il valore arriva quando hai il giusto caso d'uso che lo aspetta.
Per i team tecnici, il miglior investimento ora è comprendere il modello delle capacità, sperimentare un runtime del server su un problema reale e misurare. La tecnologia è maturata abbastanza per lasciare il laboratorio, e abbastanza presto perché conoscerla bene sia un vantaggio competitivo.
Se sei a capo dell'architettura e stai valutando questa decisione, vale la pena leggere [quando WebAssembly ripaga davvero] prima di impegnarsi in una tabella di marcia.
Leggi anche
- Router per app Next.js: la guida al Thinking Server per impostazione predefinita
- WebAssembly e componenti portabili: la promessa del modello a componenti
- WebAssembly al limite: perché è importante iniziare in modo rapido e isolato
- WebAssembly per leader: quando vale la pena scegliere l'architettura
- Edge computing: perché l'elaborazione distribuita ridefinirà la tua architettura
- Architettura dell'Edge Computing: strategie per l'elaborazione distribuita
