![]() |
WebAssembly (abbreviato in Wasm) è un linguaggio binario portabile e performante pensato per eseguire codice vicino alla velocità nativa direttamente nel browser. In questo articolo esploreremo cos'è, come funziona, le sue potenzialità, il supporto nei browser moderni e forniremo anche un esempio pratico end-to-end con Rust e JavaScript.
Cos’è WebAssembly?
WebAssembly è uno standard aperto (W3C) pensato per portare sul web codice compilato da linguaggi come Rust, C/C++, Go e molti altri, offrendo prestazioni molto elevate e sicurezza in un ambiente sandbox.
Standardizzazione
Wasm è stato ufficialmente riconosciuto come standard del web dal W3C nel 2019.
Caratteristiche principali:
-
Portabilità: può girare ovunque, anche al di fuori del browser (formato binario portabile e ottimizzato).
-
Prestazioni elevate: velocità paragonabile al codice nativo.
-
Sicurezza: esecuzione in sandbox, senza accesso diretto al sistema.
-
Interoperabilità: può interagire in modo efficiente con JavaScript e le API Web.
Come funziona WebAssembly
Il codice scritto in linguaggi come Rust viene compilato in un modulo .wasm, che può poi essere caricato nel browser tramite JavaScript. Il browser esegue quel modulo in sandbox con prestazioni quasi native.
Pipeline tipica:
-
Scrivi il codice in un linguaggio compilabile in Wasm (es. Rust).
-
Compili in un modulo
.wasm. -
Lo carichi nel browser usando JavaScript.
-
Esegui e interagisci con i dati tramite chiamate tra Wasm e JS.
Esempio JS per caricare un modulo Wasm:
fetch('modulo.wasm')
.then(res => res.arrayBuffer())
.then(bytes => WebAssembly.instantiate(bytes))
.then(obj => {
console.log(obj.instance.exports.miaFunzione());
});Esempio pratico end-to-end: WebAssembly + JavaScript
-
Installare Rust e creare un progetto Rust
Scrivere una semplice funzione in Rust che elabora un'informazione.
-
Compilarla in un modulo WebAssembly (
.wasm) usandowasm-pack. -
Caricare il modulo in una pagina HTML con JavaScript.
-
Stampare in
console.logun oggetto restituito dal modulo Wasm.
1. Installare Rust e wasm-pack (Linux, macOS, Windows)
Linux/macOS
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
cargo install wasm-pack
Windows
-
Vai su https://rustup.rs e scarica l’installer per Windows.
-
Dopo l’installazione, apri PowerShell e installa:
cargo install wasm-pack
npm install -g wasm-pack2. Creare il progetto Rust
cargo new wasm-demo --lib
cd wasm-demo
Modifica Cargo.toml:
[package]
name = "wasm_demo"
version = "0.1.0"
edition = "2021"
[lib]
crate-type = ["cdylib"]
[dependencies]
wasm-bindgen = "0.2"
serde = { version = "1.0", features = ["derive"] }
src/lib.rs:use wasm_bindgen::prelude::*;
use serde::{Serialize};
#[derive(Serialize)]
pub struct ResultObject {
pub processed: String,
pub length: usize,
}
#[wasm_bindgen]
pub fn process_input(input: &str) -> JsValue {
let result = ResultObject {
processed: input.to_uppercase(),
length: input.len(),
};
JsValue::from_serde(&result).unwrap()
}
- prende una stringa in input, la trasforma in maiuscolo e restituisce un oggetto JSON con il risultato.
- esporta la funzione process_input per poter essere richiamata da JavaScript.
3. Compila per WebAssembly con wasm-pack
cd wasm_demo
wasm-pack build --target web
4. Caricamento e utilizzo in HTML/JavaScript
pkg/ generata da wasm-pack in una directory accessibile da HTML.Crea una pagina HTML - es. index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Wasm Demo</title>
<script type="module">
import init, { process_input } from './pkg/wasm_demo.js';
async function run() {
await init();
const result = process_input("ciao wasm!");
console.log("Risultato:", result);
}
run();
</script>
</head>
<body>
<h1>WebAssembly Demo</h1>
</body>
</html>
index.html in un browser compatibile, vedrai in console qualcosa del tipo:Output atteso in console:
Risultato: { processed: "CIAO WASM!", length: 10 }Un momento: ma qual è la differenza tra il file modulo.wasm visto all'inizo e il file wasm_demo.js dell'esempio precedente?
modulo.wasm e wasm_demo.js (o qualsiasi file .js generato da wasm-pack) è fondamentale per capire come funziona l’integrazione tra WebAssembly e JavaScript. Descriviamoli in modo chiaro:1. modulo.wasm – Il modulo binario WebAssembly
Questo è il vero modulo compilato. Contiene il codice macchina portabile generato da Rust (o C/C++) in formato binario .wasm.
-
È quello che il browser esegue in sandbox.
-
Non contiene alcuna logica di caricamento o collegamento con JS.
-
Devi istanziarlo manualmente in JavaScript usando le API
WebAssembly.instantiate.
Esempio minimale di caricamento diretto:
const response = await fetch('modulo.wasm');
const bytes = await response.arrayBuffer();
const { instance } = await WebAssembly.instantiate(bytes);
console.log(instance.exports.miaFunzione());2. wasm_demo.js – Il wrapper JavaScript generato da wasm-pack
Questo file viene generato automaticamente da wasm-pack, uno strumento da riga di comando sviluppato dalla community Rust (sotto il progetto rustwasm) che semplifica il processo di compilazione di progetti Rust in WebAssembly per l’uso nel web, in particolare con JavaScript.
wasm-pack serve da ponte tra WebAssembly e il mondo JavaScript.
Esempio:
import init, { process_input } from './pkg/wasm_demo.js';
await init(); // inizializza il modulo .wasm
const result = process_input("ciao wasm");
console.log(result);Quando compili con wasm-pack, ottieni due file principali:
wasm_demo_bg.wasm: il modulo WebAssembly vero e proprio.wasm_demo.js: un wrapper JavaScript generato dawasm-packche:- Carica il modulo
.wasm. - Gestisce conversioni tra tipi Rust e JavaScript.
- Espone le funzioni in modo idiomatico per JS.
Nota:wasm_demo_bg.wasmè il nome vero generato dawasm-pack, mentremodulo.wasmè un esempio generico usato nei tutorial/manuali.
Riassunto della differenza
| File | Contenuto | Ruolo principale |
|---|---|---|
wasm_demo_bg.wasm |
Codice binario Wasm compilato da Rust | Eseguito dal browser (core) |
wasm_demo.js |
Wrapper JavaScript | Collegamento JS ↔ Wasm (gestione tipica) |
Quando usare uno o l’altro?
-
Solo
modulo.wasm→ se stai lavorando manualmente con WebAssembly usando solo le API WebAssembly standard in JS e se vuoi il massimo controllo (serve codice manuale e non supporta tipi complessi senza lavoro extra). -
wasm_demo.js+.wasm→ se vuoi semplificarti la vita e usare funzioni con stringhe o JSON. Ad esempio se usi Rust + wasm-pack + wasm-bindgen, che è il metodo moderno e più produttivo.
Caricamento manuale di un modulo .wasm [per curiosi e accademici]
Se arrivato a questo punto sei curioso di sapere come sarebbe caricare manualmente un modulo wasm in JavaScript senza passare da wasm-pack, o semplicemente vuoi approfondire il funzionamento a basso livello, allora questo paragrafo è l'ideale per capire step-by-step come funziona l'integrazione tra Wasm e JS.1. Modulo Wasm semplificato in Rust
Ai fini di questo tutorial (e per evitare che questo articolo introduttivo su Wasm sia infinito), dovremo evitare funzioni complesse e non usare wasm-bindgen (tutto ciò per rendere il caricamento manuale più semplice da effettuare). Scriveremo una funzione semplice che restituisce un numero.
src/lib.rs (senza wasm-bindgen)
#[no_mangle]
pub extern "C" fn square(x: i32) -> i32 {
x * x
}
Nota:
-
#[no_mangle]serve per evitare che il compilatore cambi il nome della funzione. -
extern "C"rende la funzione compatibile con la chiamata da linguaggi esterni (C / JS).
2. Compilazione in .wasm manuale
Compila con cargo e wasm32-unknown-unknown:
rustup target add wasm32-unknown-unknown
cargo build --release --target wasm32-unknown-unknown
Il file .wasm lo trovi qui:
target/wasm32-unknown-unknown/release/<nome_progetto>.wasm
Copialo in una cartella accessibile dal tuo progetto web.
3. HTML + JS senza wrapper
index.html
<html>
<head>
<meta charset="UTF-8"></meta>
<title>Manual Wasm</title>
<script>
async function loadWasm() {
const response = await fetch('modulo.wasm');
const bytes = await response.arrayBuffer();
const { instance } = await WebAssembly.instantiate(bytes);
const result = instance.exports.square(7);
console.log("Il quadrato di 7 è:", result);
}
loadWasm();
</script>
</head>
<body>
<h1>WebAssembly senza wrapper</h1>
</body>
</html>
Output in console:
Il quadrato di 7 è: 49
Differenze principali rispetto al wrapper wasm-pack
| Caricamento manuale | Con wasm-pack (wasm_demo.js) |
|---|---|
| Devi gestire tutto a basso livello | Espone funzioni e conversioni comode |
| Non puoi usare tipi complessi (stringhe, oggetti) senza lavoro extra | Supporta stringhe, JSON, oggetti via wasm-bindgen |
Richiede #[no_mangle] e extern "C" |
Usa macro Rust idiomatiche |
| Più adatto per moduli minimalisti | Più adatto per applicazioni moderne |
Supporto Browser
WebAssembly è supportato nei principali browser a partire dalle seguenti versioni:
| Browser | Supporto Wasm da | Versione |
|---|---|---|
| Google Chrome | Marzo 2017 | 57 |
| Mozilla Firefox | Marzo 2017 | 52 |
| Microsoft Edge | Ottobre 2017 | 16 |
| Apple Safari | Settembre 2017 | 11 |
| Opera | Marzo 2017 | 44 |
Puoi verificarlo anche su Can I Use.
Estensioni e futuro di WebAssembly
WebAssembly continua a evolversi, tra le funzionalità avanzate in fase di standardizzazione:
-
WASI (WebAssembly System Interface): esecuzione server-side.
-
Garbage Collection: per linguaggi con memoria gestita (es. Kotlin, C#).
-
Threading e SIMD: per performance parallele e operazioni vettoriali.
-
Exception Handling: migliore gestione degli errori.
Alcuni casi d’uso reali:
- Gaming (Unity via WebGL + Wasm)
- App desktop (es. Figma usa WebAssembly)
- Criptografia client-side
- Video/audio processing direttamente in JS
Risorse ufficiali e tutorial
Documentazione:
Tool e ambienti:
Tutorial pratici:
Conclusione
WebAssembly rappresenta una delle evoluzioni più importanti del web moderno. Porta sul browser codice compilato ad alte prestazioni in modo sicuro e versatile. Saperlo usare, anche solo per estendere le capacità di JavaScript, è una skill preziosa per sviluppatori frontend e backend. E grazie a strumenti come wasm-pack, l’ingresso nel mondo Wasm è oggi molto più accessibile.
Follow me #techelopment
Official site: www.techelopment.it
facebook: Techelopment
instagram: @techelopment
X: techelopment
Bluesky: @techelopment
telegram: @techelopment_channel
whatsapp: Techelopment
youtube: @techelopment
