I ett par decennier har det funnits bara ett programspråk som kan användas direkt i webbläsare: Javascript. Eftersom binära insticksprogram från tredjepartsföretag har tynat bort är språk som Java och Actionscript från Flash inte längre särskilt aktuella för webbutveckling. Och andra webbutvecklingsspråk som Coffeescript kompileras ju till Javascript.
Men nu finns det ett alternativ: Webassembly, förkortat Wasm. Webassembly är ett kompakt och snabbt binärt format som utlovar nästan maskinkodsprestanda för webbapplikationer. Dessutom är Webassembly gjort för att vara kompileringsmål för många språk – Javascript är bara ett av dem.
Alla ledande webbläsare har numera stöd för Webassembly. Därför är det dags att allvarligt tänka på att skriva klientsideapplikationer som kan kompileras som Webassembly.
Man bör komma ihåg att Webassembly-appar inte är tänkta att ersätta Javascript-appar – åtminstone inte ännu. Man bör i stället se Webassembly som ett komplement till Javascript. Javascript är flexibelt, dynamiskt typat och levereras i form av källkod som människor kan läsa. Webassembly, däremot, är supersnabbt, hårt typat och levereras i ett kompakt binärt format.
Utvecklare bör fundera på Webassembly för prestandakrävande användningsområden som spel, strömmande musik, videoredigering och cad-applikationer. Många webbaserade tjänster har redan börjat med Webassembly, till exempel Google Earth. Figma, en app för kollaborativt ritande och diagramframställning, valde Webassembly för att korta laddningstiderna och exekveringstiderna redan när Webassembly var ganska nytt.
Så fungerar Webassembly
Webassembly, som har utvecklats av webbens ledningsgrupp W3C, är, som dess skapare uttrycker det, ett ”kompileringsmål”. Utvecklare skriver inte direkt i Webassembly. De skriver i det språk de själva föredrar, och det kompileras sedan till Webassemblys bytekod. Bytekoden körs sedan på klienten – vanligtvis en webbläsare – där den översätts till maskinkod och körs i hög hastighet.
Webassemblys kod är gjord för att vara snabbare att ladda, parsa och exekvera än Javascript. När Webassembly körs i en webbläsare får man räkna med tidsåtgång för att ladda Wasm-modulen och rigga upp den. För större Wasm-projekt kan modulerna uppgå till flera megabyte, så det kan bli märkbart. Men om allt annat är lika så är Webassembly snabbare.
Webassembly erbjuder också exekvering i en sandlåda enligt samma säkerhetsmodell som Javascript har. Wasm-applikationer kan inte komma åt någonting utanför sandlådan direkt, inte heller DOM (document object module) för den sida de körs på. All interaktion med resten av datorn måste använda ABI:er som Webassembly system interface, Wasi. Wasi ger kontrollerad åtkomst till filer, nätverk, systemklocka och andra systemtjänster som ofta behövs i program.
För närvarande är det vanligtvis så att Webassembly körs i webbläsare, men det är tänkt att bli mer än så. Wasmer-projektet kör Webassembly-program på serversidan, ungefär som Node.js kör Javascript utanför webbläsaren.
Användning av Webassembly
Den grundläggande användningen av Webassembly är som målspråk för program som ska köras i webbläsare. Komponenterna som ska kompileras till Webassembly kan skrivas i valfritt av flera programspråk. Den färdiga Webassembly-lasten levereras sedan till klienten som om det var Javascript.
Webassembly har utformats med tanke på ett antal prestandakrävande, webbläsarbaserade användningsområden – spel, strömmande musik, videoredigering, cad, kryptering och bildigenkänning, för att nämna några.
Det kan vara lämpligt att utgå från dessa tre områden när du ska bestämma dig för hur du ska använda Webassembly:
- Högprestandakod som du redan har i ett kompilerbart språk. Om du till exempel har en mycket snabb matematisk funktion som är skriven i C, och du vill lägga in den i en webbaserad applikation, kan du lägga in den som en Webassembly-modul. Mindre prestandakritiska, användartillvända delar av programmet kan vara kvar i Javascript..
- Högprestandakod som behöver skrivas från grunden, och som inte lämpar sig för Javascript. Tidigare använde man kanske asm.js för att skriva sådan kod. Det kan man fortfarande göra, men Webassembly börjar ses som en bättre långsiktig lösning.
- Portering av ett skrivbordsprogram till webbaserad form. Många uppvisningar av asm.js och Webassembly har den inriktningen. Webassembly kan ge programmen ett inre maskineri som är mer ambitiöst än bara ett grafiskt användargränssnitt skriver i html. Se till exempel demos av WebDSP och Windows 2000 i webbläsare.
Vilka språk stöder Webassembly?
Webassembly är som sagt inte avsett att skrivas direkt. Som namnet antyder påminner det mer om ett assemblerspråk, något som datorn kan tugga i sig, än om ett människovänligt högnivåspråk. Webassembly är snarast ett mellanspråk som genereras i en kompileringsinfrastruktur av typ LLVM. Det är inte som C eller Java.Därför går det flesta scenarier för arbete med Webassembly ut på att man skriver kod i ett högnivåspråk och omvandlar det till Webassembly. Det kan göras på något av dessa tre sätt:
- Direkt kompilering. Källkoden omvandlas till Webassembly med användning av språkets egen verktygslåda för kompilering. Rust, C/C++, Kotlin/Native och D har alla inbyggda sätt att generera Wasm för kompilatorer avsedda för dessa språk.
- Tredjepartsverktyg. Språket har inte stöd för Wasm i verktygslådan, men verktyg från tredje part kan användas för kompilering till Wasm. För Java, Lua och Dotnet-familjen finns det sådana hjälpmedel.
- Webassembly-baserad programtolk. I detta fall är det inte själva språket som omvandlas till Webassembly. I stället är det en programtolk för språket, skriven i Webassembly, som kör kod skriven i det aktuella programspråket. Detta är det mest omständliga arbetssättet. Programtolken kan bestå av åtskilliga megabyte kod, men det gör att existerande kod skriven i det aktuella språket kan köras i oförändrad form. Python (genom till exempel Pyscript och Ruby har båda programtolkar som översätter till Wasm.
Webassemblys funktioner
Webassembly är fortfarande i barnstadiet. Webassemblys verktygskedja och dess realisering är närmare demostadiet än redo för skarp drift. Men de ansvariga för Webassembly är inställda på att göra Webassembly mer användbart genom en rad initiativ:Sophämtningsprimitiver
Webassembly ger inte direkt stöd för språk som använder sophämtningsbaserade (garbage collection) minnesmodeller. Språk som Lua och Python kan få stöd bara om man begränsar funktionsuppsättningen eller om man bäddar in hela programkoden som körbar Webassembly. Men det pågår arbete för stötta sophämtningsbaserade minnesmodeller oavsett språk och realisering.Trådar
Inbyggt stöd för trådar är vanligt i språk som Rust och C++. Eftersom det saknas stöd för trådar i Webassembly är det hela klasser av potentiell Webassembly-mjukvara som inte kan skrivas i de språken. Ett förslag om att förse Webassembly med stöd för trådar är inspirerat av hur detta görs i C++.Massdatahantering och SIMD
Massdatahantering och SIMD (single instruction, multiple data) är oumbärliga för program som tuggar sig igenom mängder med data och som behöver inbyggd cpu-accelerering för att inte kvävas – till exempel maskininlärning och vetenskapliga program. Det finns förslag om att utöka Webassembly med dessa möjligheter.Konstrukter i högnivåspråk
Många andra funktioner som har föreslagits för Webassemply har direkta motsvarigheter i högnivåkonstrukter i andra språk:- Undantag kan emuleras i Webassembly, men de kan inte realiseras direkt med Webassemblys instruktionsuppsättning. Den föreslagna planen för undantag gäller undantagsprimitiver som ska vara kompatibla med C++:s undantagsmodell, som sedan i sin tur kan användas av andra språk som kompileras till Webassembly.
- Referenstyper gör det lättare att skicka runt objekt som används som referenser för värdmiljön. Detta skulle göra sophämtning och en del andra högnivåfunktioner enklare att realisera i Webassembly.
- Svansrekursioner är ett designmönster som förekommer i många programspråk.
- Funktioner som returnerar multipla värden, till exempel i form av tupler i Python eller C#.
- Teckenutvidgningsoperatöreränk är en användbar matematisk operation på låg nivå. (LLVM stöder dem.)
Verktyg för avbuggning och profilering
Ett av de svåraste problemen med transpilerat Javascript var svårigheterna med avbuggning och profilering. Det berodde på svårigheterna med att ställa den transpilerade koden mot källkoden. Webassembly har ett likartat problem, och det hanteras på liknande sätt (stöd för källkodskarta). Se vad projektet skriver om planerat stöd för verktyg.