in

Wat is WebAssembly en wat kun je er mee?


WebAssembly klinkt hardcore, en dat is het ook. Een soort machinetaal voor high-performance webapps. Ondertussen wordt het ondersteund door alle grote browsers en is het gestandaardiseerd door het W3C. Wat is WebAssembly precies en waar wordt het in de praktijk voor gebruikt?

De voertaal voor webapps is javascript. Ondanks de succesvolle inspanningen van browsermakers om hun javascript-engines in elke versie weer wat efficiënter te maken, is dat voor veel toepassingen nog niet genoeg. Google kwam dan in 2011 met zijn Native Client (NaCl) om native processorcode in een webapp te draaien.

Mozilla wilde de platformonafhankelijkheid van javascript echter niet verlaten, en begon daarom in 2013 aan een andere aanpak: asm.js, een subset van javascript die browsers heel efficiënt kunnen uitvoeren. Je compileert dan een webapp uit een taal zoals C naar asm.js, en je browser voert dit dan als gewone javascript uit.

Het voordeel van asm.js is dat het gewoon al in alle webbrowsers werkte, maar Mozilla botste tegen de snelheidsgrenzen van javascript aan. Omdat javascript een tekstformaat heeft, vraagt het parsen veel rekenkracht, zeker op mobiele toestellen met een wat zwakkere processor. En zo werd in 2015 WebAssembly geboren, een binair instructieformaat voor een virtuele machine in je webbrowser.

Sneller

WebAssembly is dus geen nieuwe programmeertaal, maar een binair formaat voor uitvoerbare programma’s. In de praktijk kan een webontwikkelaar dus gewoon in javascript blijven programmeren en zijn .js-bestanden naar WebAssembly (met de extensie .wasm) compileren.

Het bestandsformaat is ontworpen om zo klein mogelijk te zijn en zo snel mogelijk te parsen. Vergeleken met gecomprimeerde javascript (met gzip) is een functioneel identiek WebAssembly-bestand 10 tot 20 procent kleiner. Maar de grootste snelheidswinst haalt WebAssembly bij het parsen: het binaire formaat is een factor tien sneller te parsen dan het tekstgebaseerde javascript. Het downloaden en parsen zijn twee taken die de opstarttijd in belangrijke mate bepalen, en op beide gebieden is WebAssembly geoptimaliseerd: in totaal zo’n twintig keer sneller.

Maar ook na de opstart is WebAssembly sneller. Het formaat is immers niet beperkt tot wat in javascript uitgedrukt kan worden. Daardoor kan een WebAssembly-programma rechtstreeks gebruikmaken van zaken die heel efficiënt in een moderne processor uitgevoerd worden, zoals rekenen met 64bit-getallen.

De snelheidswinst hangt uiteraard af van het feit of je code deze functies gebruikt. Gemiddeld gezien ziet Mozilla met WebAssembly een vijf procent snelheidswinst vergeleken met asm.js, maar bij encryptiecode kan dat een grootteorde groter zijn. WebAssembly haalt een zo goed als native snelheid.

Universeel formaat

Maar je kunt ook code in heel wat andere programmeertalen naar WebAssembly compileren. Elke programmeertaal die door het compilerinfrastructuurproject LLVM ondersteund wordt, kun je in principe gebruiken. Daarbij zitten onder andere C#, Haskell, Kotlin, Lua, Ruby en Rust. WebAssembly is gewoon een extra compilertarget voor die talen, en te vergelijken met een universele bytecode zoals voor Java.

De snelheid van WebAssembly hangt niet alleen af van de virtuele machine waarop de code wordt uitgevoerd, maar ook van de gebruikte compilerinfrastructuur. Een populaire toolchain voor asm.js en WebAssembly is het op LLVM gebaseerde Emscripten, dat C(++)-code compileert tot geoptimaliseerde code voor het web en daarbij ook bijvoorbeeld OpenGL-code naar WebGL omzet.

WebAssembly ontstond vanaf het begin als een samenwerking tussen Mozilla, Microsoft, Google, Apple en anderen, in de schoot van het World Wide Web Consortium. Het is zwaar op asm.js gebaseerd en gebruikt ook inzichten uit het project Portable Native Client (PNaCl), Google’s platformonafhankelijke versie van NaCl. WebAssembly moet het beste van beide werelden verenigen.

Al het werk gebeurt in de WebAssembly Community Group van het W3C. Op 18 juli publiceerde die de WebAssembly Core Specification als een W3C Candidate Recommendation. De verwachting is dat dit als standaard (‘W3C Recommendation’) aangenomen wordt.

De ontwikkeling van WebAssembly

  • 2008 –Wapenwedloop voor snelheid begint met javascript-engines als V8, TraceMonkey en Nitro
  • 2011 Google introduceert Native Client (NaCl)
  • 2013 – Mozilla ondersteunt asm.js in Firefox Nightly
  • 2015 – WebAssembly wordt aangekondigd
  • 2016 – De belangrijkste functies in WebAssembly zijn gedefinieerd
  • 2017 – Alle grote webbrowsers ondersteunen WebAssembly
  • 2018 – De WebAssembly Working Group publiceert drie W3C Candidate Recommendations

Interoperabiliteit

Precies door die samenwerking van in het begin ondersteunden al in 2017 – nog geen twee jaar na de aankondiging van het project – alle grote webbrowsers WebAssembly, zowel op de desktop als mobiel. Voor oudere webbrowsers kun je een .wasm-bestand overigens gewoon compileren naar asm.js. Dat kan automatisch met een zogenoemde ‘polyfill’: javascript-code die het .wasm-bestand op ondersteunde webbrowsers rechtstreeks uitvoert en in het andere geval compileert naar asm.js en de resulterende javascript-code uitvoert. Twijfel je of je browser WebAssembly ondersteunt, kijk dan eens op de website Can I Use.

WebAssembly is geen alles-of-nietsverhaal. Met de WebAssembly javascript-API laad je eenvoudig WebAssembly-modules in javascriptcode in. Je hoeft dus zelf niet eens iets van WebAssembly te kennen om toch in je webapp te kunnen profiteren van de snelheidswinst. Samen met de stijgende populariteit van WebAssembly zullen er ook meer en meer .wasm-bibliotheken opduiken. Zo heeft Microsoft Blazor, waarmee je C#-code rechtstreeks in de webbrowser draait, inclusief gebruik van bestaande .NET-bibliotheken.

Binaire code

Het binaire formaat laat toe om eenvoudiger code in een website te verbergen. Bovendien is een .wasm-bestand gecompileerd, inclusief allerlei optimalisaties, wat de analyse ervan nog complexer maakt. Het mag dan ook niet verbazen dat malware wasm omarmt. Maar het is slechts een kwestie van tijd voor antimalwaresoftware wasm even goed kan analyseren als native Windows-programma’s.

Ook voor nieuwsgierige powerusers klinkt het binaire formaat op het eerste gezicht niet zo interessant: daar kun je immers niet zomaar de broncode van bekijken zoals bij javascript. Maar daar heeft de WebAssembly Working Group iets voor voorzien: er is ook een tekstgebaseerd formaat: .wat. Een .wasm-bestand kan met tools zoals de WebAssembly Binary Toolkit eenvoudig naar .wat omgezet worden en omgekeerd. Ook de browsermakers geven in hun debugtools de mogelijkheid om de broncode van een .wasm-bestand op de webpagina die je bezoekt te bekijken.

OpenMediaVault op Raspberry Pi 4 installeren

Hoe blijft Mozilla overeind naast het machtige Chrome?