Was ist mit WebAssembly passiert?
(emnudge.dev)- WebAssembly (Wasm) wird weiterhin als Kerntechnologie in verschiedenen realen Produkten eingesetzt und spielt eine wichtige Rolle in Game-Engines, Design-Tools und Web-Containern
- Die Sprache selbst besitzt eine Struktur, die sich effizient auf Hardware abbilden lässt, und wurde mit Fokus auf Sicherheit und Portabilität entworfen
- Das Sicherheitsmodell folgt dem Prinzip „deny-by-default“ und ermöglicht Isolierung auf Prozessebene sowie hohe Ausführungsgeschwindigkeit
- Durch ein Plugin-Ökosystem und Cross-Language-Unterstützung wird Wasm in vielen Umgebungen genutzt, doch eine Verbreitung auf dem Niveau eines Ersatzes für das gesamte Browser-Ökosystem gibt es bislang nicht
- Derzeit ist WebAssembly tief auf Bibliotheks- und Runtime-Ebene integriert; zugleich schreiten Standardisierung und Funktionserweiterungen schnell voran
Praxisbeispiele
- WebAssembly übernimmt Kernfunktionen in Godot, Figma, Stackblitz, Squoosh.app, Zellij, Ruffle usw.
- Godot nutzt es für Web-Game-Builds, Figma zur Umwandlung von C++-Code in eine Form, die im Browser ausgeführt werden kann
- Stackblitz verwendet Wasm für Web-Container, Ruffle als Flash-Emulator
- Allerdings sind große Websites, die vollständig auf Wasm basieren, selten; meist wird es für einzelne Funktionsbereiche eingesetzt
Definition und Geschwindigkeit von WebAssembly
- WebAssembly ist eine Sprache, deren Geschwindigkeit nicht eigenständig definiert ist, sondern von der Engine-Leistung abhängt
- Wie bei JavaScript bestimmen Runtime-Engines (V8, SpiderMonkey usw.) die Ausführungsgeschwindigkeit
- WebAssembly besitzt eine Struktur, die sich effizient auf moderne Hardware abbilden lässt, und kann sowohl kompiliert als auch interpretiert werden
Struktur für effizientes Mapping
- Wasm ist ein Bytecode nahe an Assemblersprache, der sich für die meisten Hardwareplattformen ohne Verluste kompilieren lässt
- WAT (WebAssembly Text) ist die Textdarstellung von Wasm und lässt sich nahezu 1:1 umwandeln
- Ähnlich wie JVM-Bytecode, aber mit kleiner API und starken Sicherheitsgarantien
- Speicherzugriffe sind explizit, und es können nur Ressourcen verwendet werden, die von der Host-Umgebung erlaubt wurden
Wasm als Compile-Target
- Viele Sprachen wie Rust, C, Zig, Go, Kotlin, Java, C# lassen sich nach Wasm kompilieren
- Auch interpretierte Sprachen wie Python, PHP, Ruby können als Wasm-Builds ausgeführt werden
- Browser enthalten standardmäßig eine Wasm-Engine; außerdem gibt es eigenständige Runtimes wie Wasmtime, WasmEdge, Wasmer
- Ein einzelnes Wasm-Artefakt kann hardwareunabhängig ausgeführt werden
Sicherheitsarchitektur und Einsatz
- WebAssembly verwendet ein „deny-by-default“-Sicherheitsmodell; externer Zugriff ist nur über explizite Imports erlaubt
- Verborgener Control-Flow-Stack, linearer Speicher und eingeschränkter Befehlssatz sorgen für starke Isolierung
- Cloudflare isoliert die Ausführung von Wasm-basiertem Code mithilfe von V8-Isolates, Fermyon bietet Startzeiten im Submillisekundenbereich
- Ruffle stellt Flash-Inhalte sicher wieder her, Pyodide führt Python in Wasm aus, Figma führt Plugins mit einem Wasm-basierten QuickJS aus
Portabilität und Embedding
- Wasm-Runtimes sind leichtgewichtig, und Zellij, Envoy, Lapce setzen Wasm für ihre Plugin-Systeme ein
- Selbst in Umgebungen mit JavaScript-Engine können verschiedene Wasm-Bibliotheken für Bildverarbeitung, OCR, Physik-Engines, Rendering, Media-Toolkits, Datenbanken und Parser genutzt werden
- In den meisten Fällen merken Nutzer gar nicht, dass Wasm verwendet wird, da es transparent innerhalb von Bibliotheken arbeitet
Neubewertung von Geschwindigkeit und Größe
- Browser führen Wasm über dieselbe Pipeline wie JS aus; durch die Engine-Architektur bestehen Leistungsgrenzen
- Je nach Typsystem der Sprache und Grad der Compiler-Optimierung ergeben sich Unterschiede bei der Effizienz
- Kosten an der Host-Programm-Grenze und größere Binärdateien werden als Nachteile genannt
- Der WASI-Standard soll dies abmildern, doch die Standardisierung eines String-Typs ist noch nicht abgeschlossen
- Zig erzeugt die kleinsten Wasm-Binärdateien
- In nativen Umgebungen kann es durch Threading, IO und Speichernutzung zu Leistungseinbußen kommen
Entwicklungen bei Sprachen und Standards
- Die Standardisierung von Wasm wird parallel von der W3C Working Group und der Bytecode Alliance vorangetrieben
- Letztere treibt vor allem toolorientierte Entwicklungen wie WIT und das Component Model voran
- Vorschläge für neue Funktionen werden schnell übernommen, auch wenn es teils Debatten über Tempo und Richtung gibt
- Wasm verbreitet sich weniger als Ersatz für JavaScript als vielmehr als interne Integrationstechnologie
- Frameworks wie Blazor und Leptos nutzen Wasm, ohne JavaScript direkt zu behandeln
- Derzeit wird Wasm vor allem von Bibliotheksentwicklern übernommen; gewöhnliche Entwickler können es nutzen, ohne die internen Abläufe zu kennen
- Die Komplexität von Lernmaterialien gilt als Hürde, weshalb Lernprojekte wie „watlings“ vorgestellt werden
1 Kommentare
Hacker-News-Kommentare
Ich denke, Wasm hat die meisten Ziele erreicht, die man bei seiner Entstehung hatte.
Ich persönlich habe Wasm in Dutzenden Projekten als Kernbestandteil eingesetzt.
JS-Engines sind sehr schnell, aber Wasm bietet weiterhin mehr Kontrolle auf CPU-Ebene und eine hervorragende Performance.
Es hat aber die Erwartung nicht erfüllt, JS+HTML+CSS vollständig zu ersetzen. Ein großer Grund dafür ist aus meiner Sicht das Fehlen von DOM-Bindings.
Ich habe auch Wasm-Frameworks wie Yew verwendet, aber sie fühlten sich wie eine unbeholfene zusätzliche Schicht über JS an.
Blazor habe ich noch nicht benutzt, aber ich finde es immer noch angenehmer, in JS zu schreiben.
Trotzdem läuft Wasm still und leise an vielen Stellen, und ich denke, das ist der wahre Beweis für seinen Erfolg.
Zum Beispiel erreicht die Funktion zur Änderung von Audiogeschwindigkeit und Tonhöhe im Browser nur deshalb dieses Leistungsniveau, weil dafür eine C++-Bibliothek als Wasm läuft.
Wenn es ordentliche DOM-Bindings gäbe, würde JS innerhalb von 10 Jahren im Frontend verdrängt werden.
Mit C# lässt sich Code zwischen Backend und Frontend leicht teilen, und Razor-Templates werden von der IDE gut unterstützt.
Allerdings muss das komplette .NET CLR und BCL mitgeladen werden, daher ist das Bundle groß.
Weil der DOM-Zugriff schwierig ist, setzt Blazor auf einen kleinen Virtual-DOM-Renderer auf der JS-Seite.
Die Performance ist ordentlich, aber immer noch langsamer als direkt geschriebener JS-Code.
Das auf F# basierende Bolero ist ebenfalls interessant, aber das Team davon zu überzeugen ist schwierig.
Um mit dem DOM zu interagieren, braucht man dafür eine passende Hochsprache.
JS erfüllt diese Rolle gut, und die Kombination aus HTML/CSS/JS ist bereits zur gemeinsamen Sprache der UI-Entwicklung geworden.
Es gibt zwar Versuche, das Browser-Rendering aufzugeben und auf Canvas-Basis zu arbeiten, aber das ist weiterhin ein Nischenbereich.
Eine Welt, in der selbst einfache Websites mehrere MB große Runtimes herunterladen müssen, wäre schrecklich.
Die eigentliche Langsamkeit kommt nicht von JS, sondern vom DOM. Schließlich muss man damit ja doch interagieren.
Ich habe mehrere Jahre mit WebAssembly gearbeitet und werde bald ein Wasm-basiertes Framework veröffentlichen.
Das Ökosystem entwickelte sich schnell weiter, wurde dann aber plötzlich langsamer, und die Einführung von WASI und dem Component Model sorgte für Verwirrung.
Je nach Engine ist der Support unterschiedlich, sodass man oft zwischen Dokumentation, Code und Issues hin- und herwechseln muss.
Das größte Problem ist die Unterstützung für JS/TS. Aktuell ist die Art der Integration fast schon ein Hack und nicht stabil.
Web Containers haben Verbesserungen gebracht, aber viele Entwickler sind bereits zu Bun gewechselt.
Das Potenzial von Wasm ist enorm.
Theoretisch könnte es ein gemeinsames Compile-Target für alle Plattformen sein.
In der Praxis ist es aber etwas enttäuschend, wenn es am Ende vor allem darum geht, einzelne Funktionen in Figma schneller zu machen.
Dass die Entwicklung stark komiteegetrieben ist, bremst das Tempo ebenfalls.
Zu Zeiten von Native Client waren Apps mit nativer Geschwindigkeit möglich, aber das heutige Wasm ist langsamer.
Man hätte die JS-Binding-Struktur auch auf Wasm anwenden können, was schade ist.
Außerdem ist Wasm nicht einmal schneller als JS.
HTML/CSS/JS hat seinen Nutzen bereits bewiesen, während Wasm weiterhin ein ungewohnter Technologie-Stack ist.
Das Docker-zentrierte Ökosystem hält alles auf.
Viele Build-Tools im JS-Ökosystem sind in Rust geschrieben, und einige laufen im Browser als Wasm.
Auch das React- oder npm-Ökosystem nutzt intern Wasm.
Wenn Wasm verschwände, würde die JS-Frontend-Welt erheblich ins Wanken geraten.
Native Wasm-UI-Frameworks sind allerdings weiterhin schwach entwickelt.
Man ist auf DOM und CSS angewiesen und muss über JS auf Browser-APIs zugreifen, was ineffizient ist.
Man kann den DOM zwar mit Rust oder Kotlin steuern, aber Rust ist für das Frontend zu Low-Level.
Cross-Compilation für mobile Plattformen nimmt zunehmend zu, JetBrains Compose Multiplatform ist ein Beispiel dafür.
Was die Entwicklung von Wasm ausbremst, ist das Tooling.
Debugging ist weiterhin auf
printf-Niveau, und auch das DWARF-Plugin für Chrome wurde seit langem nicht aktualisiert.Der Prozess, je nach Sprache
.wasm-Dateien zu erzeugen und import/export einzurichten, ist kompliziert.Die GC-Unterstützung ist ebenfalls nicht vollständig, sodass Ökosysteme wie .NET ihre eigene GC mitbringen müssen.
WIT wirkt wie ein weiterer Versuch in Richtung COM/CORBA/gRPC.
Emscripten ist komplex und instabil, wasi-sdk ist funktionsarm.
Sowohl LLVM als auch die Engines sind unzureichend optimiert, und das Wasm-Tooling von Rust liegt faktisch brach.
Es gibt nicht einmal eine standardisierte Möglichkeit, Wasm-Module aus JS zu importieren.
Auch Multithreading setzt COOP/COEP-Header voraus und ist deshalb auf GitHub Pages nicht möglich.
Wenn das Tooling das Niveau von „Tech-Demos“ hinter sich gelassen hätte, würde es heute viel häufiger eingesetzt.
Unsere Firma Leaning Technologies setzt Wasm aktiv ein.
Mit WebVM führen wir x86-Binärdateien im Browser aus,
mit BrowserCraft Java-Apps einschließlich Minecraft,
und mit BrowserPod starten wir Node.js-Container im Browser.
Das ist sehr leistungsfähig, aber ein Werkzeug für Power-User. Allgemeine Frontend-Logik nach Wasm zu kompilieren ist ineffizient.
Das Tempo, mit dem sich CheerpJ entwickelt, sei beeindruckend, und wäre es 10 Jahre früher erschienen, hätte die Web-Plattform vielleicht anders ausgesehen.
Wer JS nicht mag, sieht gerade in einer Website ohne JS den eigentlichen Reiz von Wasm.
Ich arbeite am Rust-basierten Wasm-Framework Dioxus.
Im Frontend-Wasm fehlten grundlegende Tools wie Bundle-Splitting, Hot Reload, Debug-Symbole und Asset-Integration.
2025 wurde hier vieles verbessert, und auch die Integration mit Tools wie Vite ist besser geworden.
Dank AI-Tools ist auch die Entwicklungsgeschwindigkeit mit Rust gestiegen, und ich erwarte, dass Wasm-Frameworks künftig mehr Aufmerksamkeit bekommen.
Es wurde angemerkt, dass die Binärgröße von Wasm zu groß sei.
In DSL-Umgebungen könne der Download mehrere Sekunden bis Minuten dauern.
JS sei kleiner und lasse sich bereits während des Downloads ausführen, so das Argument.
Mit Rust gebaut lässt es sich auf 10–100 KB reduzieren.
JS wird nicht während des Downloads ausgeführt, und Wasm kann durch Streaming-Compilation sogar schneller starten.
Im Grunde werden damit Funktionen doppelt implementiert, die der Browser bereits bereitstellt.
Zum Beispiel implementiert FSHistory x86-Emulation in 24 KB.
Das native Ökosystem ist nur nicht an Optimierung auf kleine Codegröße gewöhnt.
Die Aussage im Artikel, es gebe „keine großen Websites, die mit Wasm gebaut wurden“, passt nicht zu meiner Erfahrung.
Das Ziel von Wasm-Projekten war nie, die komplette Web-App zu ersetzen.
Es wirkt eher so, als hätten die Leute falsche Erwartungen entwickelt und fragten nun: „Warum ist das nicht passiert?“
Ich habe Wasm tatsächlich in mehreren Praxisfällen eingesetzt.
Dann könne man nur die nötigen Teile im Backend herausschneiden und ausliefern.