WebAssembly (WASM) begann als Moglichkeit, C++ im Browser auszufuhren. Im Jahr 2026 lauft es uberall - Browser, Server, Edge-Netzwerke, eingebettete Gerate - und betreibt einige der anspruchsvollsten Anwendungen im Web. Figmas Rendering-Engine, Adobe Photoshop im Web, die Videoverarbeitung von Google Meet und Cloudflares Edge-Compute-Plattform laufen alle auf WebAssembly.
Chrome Platform Status beziffert WASM auf etwa 5,5 % aller Chrome-Seitenaufrufe Anfang 2026, gegenuber 4,5 % im Vorjahr. Mit WASM 3.0 als W3C-Standard und WASI auf dem Weg zur Version 1.0 hat das Okosystem einen Wendepunkt erreicht.
Dieser Leitfaden behandelt alles, was du wissen musst, um mit WebAssembly zu entwickeln.
Was ist WebAssembly?
WebAssembly ist ein binares Befehlsformat, das als Kompilierungsziel konzipiert wurde. Du schreibst Code in einer Hochsprache (Rust, C, C++, Go, Kotlin), kompilierst ihn zu .wasm und fuhrst ihn in jeder Umgebung aus, die eine WASM-Laufzeitumgebung hat - Browser, Node.js, Cloudflare Workers, Wasmtime oder Wasmer.
Wie es funktioniert
WASM ist eine stapelbasierte virtuelle Maschine. Funktionen legen Werte auf einem Operandenstapel ab und nehmen sie wieder herunter. Die Host-Laufzeitumgebung (V8 in Chrome, SpiderMonkey in Firefox) kompiliert den WASM-Bytecode per JIT zu nativem Maschinencode, weshalb die Leistung nahezu nativ ist.
Wichtige Eigenschaften:
- Isolierte Ausfuhrung: WASM-Module konnen nur auf Ressourcen zugreifen, die der Host explizit gewahrt. Kein Dateisystem, kein Netzwerk, kein Betriebssystemzugriff, es sei denn, er wird erlaubt. Das ist grundlegend anders als nativer Code.
- Linearer Speicher: ein einzelner zusammenhangender
ArrayBuffer, der zwischen WASM und dem Host geteilt wird. Komplexe Daten (Strings, Structs) werden durch Schreiben in den Speicher und Teilen eines Pointers ubergeben. - Typbeschrankt: WASM unterstutzt nativ nur vier Typen:
i32,i64,f32,f64. Alles andere (Strings, Arrays, Objekte) erfordert Kodierung uber linearen Speicher oder das Component Model. - Portabel: dieselbe
.wasm-Binardatei lauft auf jeder Plattform mit einer WASM-Laufzeitumgebung, ohne Neukompilierung.
WASM vs JavaScript
WASM ersetzt JavaScript nicht. Es erganzt es.
| Aspekt | JavaScript | WebAssembly |
|---|---|---|
| Parsing | Parsen + Kompilieren zur Laufzeit | Vorkompilierte Binardatei, nur Dekodierung |
| Ausfuhrungsgeschwindigkeit | JIT-optimiert, variabel | Nahezu nativ, konsistent |
| Startzeit | Schnell fur kleine Skripte | Schnelle Dekodierung, vorhersagbar |
| DOM-Zugriff | Direkt | Indirekt (uber JS-Glue-Code) |
| Am besten fur | UI, DOM-Manipulation, Event-Handling | CPU-intensive Berechnungen |
| Garbage Collection | Eingebaut | WasmGC (neu) oder manuell |
Verwende JavaScript fur UI- und DOM-Arbeit. Verwende WASM fur rechenintensive Aufgaben: Bildverarbeitung, Videokodierung, Physiksimulationen, Kryptografie, Datenverarbeitung.
WASM 3.0: Was ist neu
WebAssembly 3.0 wurde im September 2025 zum W3C-Standard und standardisierte neun Features, die seit Jahren in Entwicklung waren.
| Feature | Was es ermoglicht |
|---|---|
| WasmGC | Native Garbage Collection in WASM. Verwaltete Sprachen (Java, Kotlin, Dart) konnen zu WASM kompilieren, ohne ihre eigene GC-Laufzeitumgebung mitzuliefern. Unterstutzt in Chrome 119+, Firefox 120+, Safari 18.2+. |
| Exception Handling | Natives try/catch in WASM. Zuvor erforderten Exceptions teure Roundtrips zu JavaScript. |
| Tail Calls | Ermoglicht effiziente Rekursion ohne Stack Overflow. Entscheidend fur funktionale Sprachen. |
| Relaxed SIMD | 128-Bit-Vektorbefehle fur parallele Datenverarbeitung. Ermoglicht hardwarespezifische Optimierungen. |
| Memory64 | Durchbricht die 4-GB-Grenze des linearen Speichers. Erforderlich fur grossangelegte Datenverarbeitung. |
| Multi-memory | Mehrere unabhangige Speicherbereiche in einem Modul. |
Am wirkungsvollsten ist WasmGC. Zuvor bedeutete das Kompilieren von Java oder Kotlin zu WASM, einen kompletten Garbage Collector als Teil der Binardatei mitzuliefern, was die Dateigrossen aufblahte. Jetzt ubernimmt die GC des Browsers die Speicherverwaltung fur WASM-Module, genau wie fur JavaScript.
WASI: WebAssembly jenseits des Browsers
WASM im Browser ist leistungsstark, aber WASI (WebAssembly System Interface) macht WASM zu einer universellen Laufzeitumgebung. WASI bietet standardisierte Schnittstellen fur Systemressourcen - Dateien, Netzwerk, Uhren, Zufallszahlen - und ermoglicht es WASM-Modulen, ausserhalb des Browsers zu laufen.
WASI Preview 2 (das aktuelle stabile Release) definiert diese Schnittstellen:
wasi:filesystem- Dateioperationen uber Capability-Handles (nicht traditionelle Dateideskriptoren)wasi:sockets- TCP/UDP-Netzwerkwasi:http- HTTP-Request/Response-Verarbeitungwasi:clocks- Wanduhr, monotone Uhrwasi:random- kryptografischer Zufallwasi:cli- Kommandozeilenargumente, Umgebungsvariablen, Stdio
Das Schlusselprinzip ist Capability-basierte Sicherheit: Ein WASM-Modul kann nicht auf das Dateisystem zugreifen, es sei denn, der Host gewahrt explizit ein Handle fur ein bestimmtes Verzeichnis. Das macht WASI grundlegend sicherer als das Ausfuhren nativer Binardateien.
Der Weg zu WASI 1.0
WASI 0.3.0 (mit Async/Concurrency-Primitiven) wird fur 2026 erwartet, gefolgt von WASI 1.0. Die wichtigste Neuerung ist sprachintegriertes Async mit Zero-Copy-Streaming-I/O.
Das Component Model
Kern-WASM-Module konnen nur Zahlen austauschen. Das Component Model lost diese Einschrankung, indem es ein reichhaltiges Typsystem und eine Kompositionsschicht uber WASM legt.
WIT (WebAssembly Interface Types)
WIT ist eine Interface Definition Language, mit der Komponenten ihre Imports und Exports mit reichhaltigen Typen deklarieren konnen - Strings, Records, Listen, Varianten, Enums - nicht nur i32 und f64.
// calculator.wit package myorg:calculator@1.0.0; interface operations { record calculation { expression: string, result: f64, timestamp: u64, } add: func(a: f64, b: f64) -> f64; multiply: func(a: f64, b: f64) -> f64; history: func() -> list<calculation>; } world calculator { export operations; }
Toolchains wie wit-bindgen generieren sprachspezifische Bindings aus WIT-Dateien. Eine Rust-Komponente und eine Python-Komponente konnen Strings, Records und Listen uber WIT-Vertrage austauschen, ohne dass eine Seite die Implementierungssprache der anderen kennen muss.
Dein erstes WASM-Modul mit Rust bauen
Rust hat das ausgereifteste WASM-Tooling. Lass uns ein praktisches Beispiel bauen: ein Bildverarbeitungsmodul, das im Browser lauft.
Setup
# Install the WASM target for Rust rustup target add wasm32-unknown-unknown # Install wasm-pack (builds Rust to WASM + generates JS bindings) cargo install wasm-pack # Create a new library project cargo new --lib image-processor cd image-processor
Cargo.toml konfigurieren
[package] name = "image-processor" version = "0.1.0" edition = "2021" [lib] crate-type = ["cdylib"] [dependencies] wasm-bindgen = "0.2"
Den Rust-Code schreiben
// src/lib.rs use wasm_bindgen::prelude::*; /// Convert an image buffer to grayscale. /// Input: RGBA pixel data as a flat u8 array (4 bytes per pixel). /// Output: Modified in place for zero-copy performance. #[wasm_bindgen] pub fn grayscale(pixels: &mut [u8]) { for chunk in pixels.chunks_exact_mut(4) { let r = chunk[0] as f32; let g = chunk[1] as f32; let b = chunk[2] as f32; // ITU-R BT.709 luminance coefficients let gray = (0.2126 * r + 0.7152 * g + 0.0722 * b) as u8; chunk[0] = gray; chunk[1] = gray; chunk[2] = gray; // chunk[3] is alpha, leave unchanged } } /// Adjust brightness of an image. /// factor > 1.0 brightens, < 1.0 darkens. #[wasm_bindgen] pub fn adjust_brightness(pixels: &mut [u8], factor: f32) { for chunk in pixels.chunks_exact_mut(4) { chunk[0] = ((chunk[0] as f32 * factor).min(255.0)) as u8; chunk[1] = ((chunk[1] as f32 * factor).min(255.0)) as u8; chunk[2] = ((chunk[2] as f32 * factor).min(255.0)) as u8; } } /// Invert all colors in the image. #[wasm_bindgen] pub fn invert(pixels: &mut [u8]) { for chunk in pixels.chunks_exact_mut(4) { chunk[0] = 255 - chunk[0]; chunk[1] = 255 - chunk[1]; chunk[2] = 255 - chunk[2]; } } /// Calculate the average brightness of an image (0-255). #[wasm_bindgen] pub fn average_brightness(pixels: &[u8]) -> f32 { let mut total: f64 = 0.0; let pixel_count = pixels.len() / 4; for chunk in pixels.chunks_exact(4) { let luminance = 0.2126 * chunk[0] as f64 + 0.7152 * chunk[1] as f64 + 0.0722 * chunk[2] as f64; total += luminance; } (total / pixel_count as f64) as f32 }
Build
wasm-pack build --target web
Dies erzeugt ein pkg/-Verzeichnis mit:
image_processor_bg.wasm- die kompilierte WASM-Binardateiimage_processor.js- JavaScript-Glue-Code mit TypeScript-Definitionenpackage.json- bereit zur Veroffentlichung auf npm
Verwendung in JavaScript
<!DOCTYPE html> <html> <head><title>WASM Image Processor</title></head> <body> <canvas id="canvas" width="800" height="600"></canvas> <button onclick="applyGrayscale()">Grayscale</button> <button onclick="applyBrightness()">Brighten</button> <button onclick="applyInvert()">Invert</button> <script type="module"> import init, { grayscale, adjust_brightness, invert } from "./pkg/image_processor.js"; let ctx; let imageData; async function setup() { await init(); const canvas = document.getElementById("canvas"); ctx = canvas.getContext("2d"); // Load an image onto the canvas const img = new Image(); img.onload = () => { ctx.drawImage(img, 0, 0); imageData = ctx.getImageData(0, 0, canvas.width, canvas.height); }; img.src = "photo.jpg"; } window.applyGrayscale = () => { grayscale(imageData.data); ctx.putImageData(imageData, 0, 0); }; window.applyBrightness = () => { adjust_brightness(imageData.data, 1.3); ctx.putImageData(imageData, 0, 0); }; window.applyInvert = () => { invert(imageData.data); ctx.putImageData(imageData, 0, 0); }; setup(); </script> </body> </html>
Die zentrale Erkenntnis: imageData.data ist ein Uint8ClampedArray, das von einem ArrayBuffer unterstutzt wird. Wenn es an WASM ubergeben wird, teilt es denselben Speicher - kein Kopieren. Die Rust-Funktion andert Pixel direkt, und die JavaScript-Seite sieht die Anderungen sofort.
Low-Level: Manuelle WASM-Instanziierung
Wenn du wasm-bindgen nicht verwenden mochtest, kannst du WASM-Module direkt instanziieren:
const response = await fetch("calculator.wasm"); const { instance } = await WebAssembly.instantiateStreaming(response, { env: { // Functions the WASM module can call log_result: (value) => console.log("Result:", value), }, }); // Call exported functions const { add, multiply } = instance.exports; console.log(add(5, 3)); // 8 console.log(multiply(4, 7)); // 28
Das ist nutzlich, wenn du minimalen Overhead willst und kein reichhaltiges Typ-Interop brauchst.
Leistung: WASM vs JavaScript
Reale Benchmarks zeigen signifikante Beschleunigungen fur CPU-intensive Aufgaben:
| Aufgabe | JavaScript | WASM | Beschleunigung |
|---|---|---|---|
| 4K-Bildverarbeitung | 180ms | 8ms (mit SIMD) | 22x |
| Bildskalierung (4K) | 250ms | 45ms | 5,5x |
| Physiksimulation (10K Objekte) | Frame-Einbruche | Flussige 60fps | ~10x |
| JSON-Parsing (grosser Payload) | 12ms | 3ms | 4x |
| Kryptografisches Hashing | 45ms | 6ms | 7,5x |
WASM lauft mit etwa 95 % der nativen Code-Geschwindigkeit. Die grossten Gewinne kommen von:
- Vorhersagbare Leistung (kein JIT-Aufwarmen, keine GC-Pausen)
- SIMD-Befehle fur parallele Datenverarbeitung
- Direkter Speicherzugriff ohne Garbage-Collector-Interferenz
Wo WASM NICHT schneller ist: DOM-Manipulation, kleine Berechnungen, I/O-gebundene Aufgaben. JavaScript ist bereits dafur optimiert.
Produktions-Anwendungsfalle
Figma: Echtzeit-Vektor-Rendering
Figmas Kern-Rendering-Engine ist in C++ geschrieben und zu WASM kompiliert. Jede Form, jeder Verlauf und jeder Effekt wird in WASM berechnet und auf ein Canvas-Element gezeichnet. So kann Figma komplexe Designs mit Tausenden von Ebenen bei 60fps im Browser verarbeiten - eine Leistung, die in reinem JavaScript unmoglich ware.
Adobe Photoshop im Web
Adobe hat wichtige Photoshop-Filter und -Werkzeuge mit Rust nach WASM portiert. Ihre Benchmarks zeigen 4K-Bildverarbeitung in 22ms mit WASM SIMD gegenuber 180ms in JavaScript - eine 8-fache Verbesserung, die Echtzeit-Filtervorschauen ermoglicht.
Cloudflare Workers
Cloudflare fuhrt WASM-Module in V8-Isolates an uber 330 Edge-Standorten aus. Kaltstarts liegen bei 1-5ms (im Vergleich zu 100-500ms bei containerbasierten Serverless-Losungen). Im Februar 2026 haben sie Llama-3-8b-Inferenz uber ihr Edge-Netzwerk mit WASM bereitgestellt.
Google Meet
Hintergrundunschaerfe und virtuelle Hintergrunde in Google Meet nutzen WASM mit SIMD fur Echtzeit-Videoverarbeitung. Das WASM-Modul verarbeitet jeden Videoframe schnell genug, um flussiges Video bei 30fps aufrechtzuerhalten.
Browser-Unterstutzung (2026)
| Feature | Chrome | Firefox | Safari | Edge |
|---|---|---|---|---|
| Core WASM | Vollstandig | Vollstandig | Vollstandig | Vollstandig |
| Threads | Ja | Ja | Ja | Ja |
| SIMD (128-Bit) | Ja | Ja | Ja | Ja |
| WasmGC | 119+ | 120+ | 18.2+ | Ja |
| Exception Handling | Ja | Ja | Ja | Ja |
| Memory64 | Ja | Ja | Teilweise | Ja |
Alle grossen Browser unterstutzen WASM vollstandig. Die neueren Features (WasmGC, Exception Handling) sind breit verfugbar.
Tooling-Referenz
| Tool | Zweck | Installation |
|---|---|---|
| wasm-pack | Rust zu WASM bauen, npm-Pakete generieren | cargo install wasm-pack |
| wasm-bindgen | Rust/JS-Interop-Bindings (von wasm-pack genutzt) | Dependency in Cargo.toml |
| wasm-opt | Optimierung der Binardateigrosse (50%+ Reduktion) | Teil von Binaryen: brew install binaryen |
| wit-bindgen | Bindings aus WIT-Dateien generieren | cargo install wit-bindgen-cli |
| Wasmtime | Serverseitige WASM-Laufzeitumgebung (Referenz-WASI-Implementierung) | brew install wasmtime |
| Wasmer | Alternative WASM-Laufzeitumgebung mit WASI-Unterstutzung | curl https://get.wasmer.io -sSfL | sh |
| wasm-feature-detect | Laufzeit-Browser-Feature-Erkennung | npm install wasm-feature-detect |
Binardateigrosse optimieren
WASM-Binardateien konnen gross sein. So verkleinerst du sie:
# Cargo.toml [profile.release] opt-level = "z" # Optimize for size lto = true # Link-time optimization codegen-units = 1 # Better optimization, slower compile strip = true # Strip debug symbols
# Build in release mode wasm-pack build --release --target web # Further optimize with wasm-opt wasm-opt -Oz pkg/image_processor_bg.wasm -o pkg/image_processor_bg.wasm
Ein typisches Rust-WASM-Modul schrumpft mit diesen Optimierungen von 500KB auf unter 50KB.
Einstiegs-Roadmap
Fazit
WebAssembly ist nicht mehr experimentell. Es ist eine Produktionstechnologie, die von einigen der anspruchsvollsten Anwendungen im Web genutzt wird. Nahezu native Leistung, sandboxed Sicherheit und universelle Portabilitat - kein anderes Kompilierungsziel bietet dir alle drei.
Du musst nicht deine gesamte Anwendung in WASM umschreiben. Beginne mit einer einzelnen CPU-intensiven Funktion - einem Bildfilter, einem Daten-Parser, einer Physikberechnung - kompiliere sie zu WASM und rufe sie aus JavaScript auf. Miss den Unterschied. Dann entscheide, wo WASM noch helfen kann.
Das Tooling ist ausgereift, die Browser-Unterstutzung ist universell und das Okosystem wachst. Wenn du Rust schreibst, bist du bereits einen Befehl vom Browser entfernt.
Einstiegs-Checkliste:
- Rust und wasm-pack installiert
- Erstes WASM-Modul gebaut und im Browser laufend
- JavaScript-Interop funktioniert (WASM aus JS aufrufen)
- Release-Build mit Grossenoptimierungen angewendet
- Leistung gegen reines JavaScript-Aquivalent gemessen
- WASI mit Wasmtime fur serverseitige Anwendungsfalle erkundet