Cos'è WebAssembly? Spiegata la piattaforma web di nuova generazione

Da due decenni ormai, abbiamo a disposizione un solo linguaggio di programmazione da utilizzare in modo nativo in un browser web: JavaScript. La lenta morte dei plug-in binari di terze parti ha escluso altri linguaggi, come Java e ActionScript di Flash, come cittadini di prima classe per lo sviluppo web. Altri linguaggi web, come CoffeeScript, sono semplicemente compilati in JavaScript.

Ma ora abbiamo una nuova possibilità: WebAssembly o WASM in breve. WebAssembly è un formato binario piccolo e veloce che promette prestazioni quasi native per le applicazioni web. Inoltre, WebAssembly è progettato per essere un obiettivo di compilazione per qualsiasi linguaggio, JavaScript è solo uno di questi. Con tutti i principali browser che ora supportano WebAssembly, è ora di iniziare a pensare seriamente alla scrittura di app lato client per il Web che possono essere compilate come WebAssembly.

Vale la pena notare che le app WebAssembly non sono destinate a sostituire le app JavaScript, almeno, non ancora. Invece, pensa a WebAssembly come un compagno di JavaScript. Laddove JavaScript è flessibile, tipizzato dinamicamente e fornito tramite codice sorgente leggibile dall'uomo, WebAssembly è ad alta velocità, fortemente tipizzato e fornito tramite un formato binario compatto.

Gli sviluppatori dovrebbero considerare WebAssembly per casi d'uso ad alta intensità di prestazioni come giochi, streaming di musica, editing video e applicazioni CAD.

Come funziona WebAssembly

WebAssembly, sviluppato dal W3C, è nelle parole dei suoi creatori un "obiettivo di compilazione". Gli sviluppatori non scrivono direttamente WebAssembly; scrivono nella lingua di loro scelta, che viene poi compilata nel bytecode di WebAssembly. Il bytecode viene quindi eseguito sul client, in genere in un browser Web, dove viene tradotto in codice macchina nativo ed eseguito ad alta velocità.

Il codice WebAssembly è pensato per essere più veloce da caricare, analizzare ed eseguire rispetto a JavaScript. Quando WebAssembly viene utilizzato da un browser web, c'è ancora l'overhead di scaricare il modulo WASM e configurarlo, ma a parità di condizioni WebAssembly funziona più velocemente. WebAssembly fornisce anche un modello di esecuzione in modalità sandbox, basato sugli stessi modelli di sicurezza attualmente esistenti per JavaScript.

Al momento, l'esecuzione di WebAssembly nei browser Web è il caso d'uso più comune, ma WebAssembly è pensato per essere più di una soluzione basata sul Web. Alla fine, man mano che le specifiche WebAssembly si modellano e più funzionalità vi arrivano, potrebbe diventare utile in app mobili, app desktop, server e altri ambienti di esecuzione.

Casi d'uso di WebAssembly

Il caso d'uso più basilare di WebAssembly è come destinazione per scrivere software nel browser. I componenti che vengono compilati in WebAssembly possono essere scritti in una qualsiasi delle numerose lingue; il payload finale di WebAssembly viene quindi consegnato al client tramite JavaScript.

WebAssembly è stato progettato pensando a una serie di casi d'uso basati su browser ad alta intensità di prestazioni: giochi, streaming musicale, editing video, CAD, crittografia e riconoscimento delle immagini, per citarne solo alcuni.

Più in generale, è istruttivo concentrarsi su queste tre aree quando si determina il caso d'uso specifico di WebAssembly:

  • Codice ad alte prestazioni già esistente in una lingua selezionabile come target. Ad esempio, se si dispone di una funzione matematica ad alta velocità già scritta in C e si desidera incorporarla in un'applicazione Web, è possibile distribuirla come modulo WebAssembly. Le parti dell'app meno critiche per le prestazioni e rivolte agli utenti possono rimanere in JavaScript.
  • Codice ad alte prestazioni che deve essere scritto da zero, dove JavaScript non è l'ideale. In precedenza, si poteva usare asm.js per scrivere tale codice. Puoi ancora farlo, ma WebAssembly viene posizionato come una migliore soluzione a lungo termine.
  • Porting di un'applicazione desktop in un ambiente web. Molte delle demo tecnologiche per asm.js e WebAssembly rientrano in questa categoria. WebAssembly può fornire un substrato per app più ambiziose di una semplice GUI presentata tramite HTML. (Vedere le demo di WebDSP, Zen Garden e Tanks.) Questo, tuttavia, non è un esercizio banale, poiché tutti i modi in cui l'applicazione desktop si interfaccia con l'utente devono essere mappati agli equivalenti WebAssembly / HTML / JavaScript.

Se hai un'app JavaScript esistente che non sta spingendo alcun limite di prestazioni, è meglio lasciarla sola in questa fase dello sviluppo di WebAssembly. Ma se hai bisogno che l'app sia più veloce, WebAssembly potrebbe aiutarti.

Supporto linguistico WebAssembly 

WebAssembly non è pensato per essere scritto direttamente. Come suggerisce il nome, è più simile a un linguaggio assembly, qualcosa che la macchina può consumare, che un linguaggio di programmazione di alto livello e umano. WebAssembly è più vicino alla rappresentazione intermedia (IR) generata dall'infrastruttura del compilatore di linguaggio LLVM, di quanto non sia come C o Java.

Pertanto, la maggior parte degli scenari per lavorare con WebAssembly implica la scrittura di codice in un linguaggio di alto livello e la sua trasformazione in WebAssembly. Questo può essere fatto in uno dei tre modi di base:

  • Compilazione diretta. Il sorgente viene tradotto in WebAssembly tramite la toolchain del compilatore del linguaggio. Rust, C / C ++, Kotlin / Native e D ora hanno tutti modi nativi per emettere WASM da compilatori che supportano quei linguaggi.
  • Strumenti di terze parti. Il linguaggio non ha il supporto WASM nativo nella sua toolchain, ma è possibile utilizzare un'utilità di terze parti per convertire in WASM. Java, Lua e la famiglia di linguaggi .Net hanno tutti un supporto come questo.
  • Interprete basato su WebAssembly. In questo caso, la lingua stessa non viene tradotta in WebAssembly; piuttosto, un interprete per la lingua, scritto in WebAssembly, esegue il codice scritto nella lingua. Questo è l'approccio più complicato, poiché l'interprete può essere diversi megabyte di codice, ma consente al codice esistente scritto nella lingua di essere eseguito quasi senza modifiche. Python e Ruby hanno entrambi interpreti tradotti in WASM.

Funzionalità di WebAssembly

WebAssembly è ancora nelle prime fasi. La toolchain e l'implementazione di WebAssembly rimangono più vicine alla prova di concetto rispetto alla tecnologia di produzione. Detto questo, i custodi di WebAssembly mirano a rendere WebAssembly più utile attraverso una serie di iniziative:

Primitive di raccolta dei rifiuti

WebAssembly non supporta direttamente i linguaggi che utilizzano modelli di memoria raccolti in Garbage Collection. Linguaggi come Lua o Python possono essere supportati solo limitando i set di funzionalità o incorporando l'intero runtime come eseguibile WebAssembly. Ma è in corso un lavoro per supportare i modelli di memoria raccolti in modo indesiderato indipendentemente dal linguaggio o dall'implementazione.

Filettatura

Il supporto nativo per il threading è comune a linguaggi come Rust e C ++. L'assenza del supporto del threading in WebAssembly significa che intere classi di software mirato a WebAssembly non possono essere scritte in quelle lingue. La proposta di aggiungere threading a WebAssembly utilizza il modello di threading C ++ come una delle sue ispirazioni.

Operazioni di memoria di massa e SIMD

Le operazioni di memoria di massa e il parallelismo SIMD (istruzione singola, più dati) sono indispensabili per le applicazioni che macinano pile di dati e richiedono l'accelerazione nativa della CPU per evitare il soffocamento, come l'apprendimento automatico o le app scientifiche. Sono disponibili proposte per aggiungere queste funzionalità a WebAssembly tramite nuovi operatori.

Costrutti linguistici di alto livello

Molte altre funzionalità prese in considerazione per WebAssembly vengono mappate direttamente a costrutti di alto livello in altre lingue.

  • Le eccezioni possono essere emulate in WebAssembly, ma non possono essere implementate in modo nativo tramite il set di istruzioni di WebAssembly. Il piano proposto per le eccezioni coinvolge primitive di eccezione compatibili con il modello di eccezione C ++, che a sua volta potrebbe essere utilizzato da altri linguaggi compilati in WebAssembly.
  • I tipi di riferimento  semplificano il passaggio di oggetti utilizzati come riferimenti all'ambiente host. Ciò renderebbe la garbage collection e una serie di altre funzioni di alto livello più facili da implementare in WebAssembly.
  • Chiamate di coda , un modello di progettazione utilizzato in molte lingue.
  • Funzioni che restituiscono più valori , ad esempio tramite tuple in Python o C #.
  • Operatori di estensione dei segni , un'utile operazione matematica di basso livello. (LLVM supporta anche questi.)

Strumenti di debug e profilazione

Uno dei maggiori problemi con JavaScript traspilato è stata la difficoltà di debug e profilazione, a causa dell'incapacità di correlare tra il codice traspilato e il sorgente. Con WebAssembly, abbiamo un problema simile e viene risolto in modo simile (supporto mappa sorgente). Vedere la nota del progetto sul supporto pianificato per gli strumenti.