JavaScript + WebAssembly: Symbiose für hochperformante XR-Erlebnisse

Was sich im Browser-XR-Stack seit 2023 tatsächlich verschoben hat — von SIMD als Baseline bis Wasm 3.0 — und wo sich WebAssembly im Projekt wirklich lohnt.

JavaScript + WebAssembly: Symbiose für hochperformante XR-Erlebnisse

In der XR-Entwicklung setze ich bewusst auf das Duo JavaScript und WebAssembly: WebAssembly bringt die Rechenpower, JavaScript die Agilität. Seit diesem Artikel zum ersten Mal erschien, hat sich im Browser-Stack einiges verschoben — SIMD ist inzwischen Baseline, Wasm 3.0 ist Standard, und WebGPU läuft seit Ende 2025 in allen großen Browsern. Zeit für eine Bestandsaufnahme: Was hat sich bewährt, was war heiße Luft?

Wozu überhaupt zwei Sprachen?

Die Rollenverteilung ist simpel und hat sich bewährt:

  • JavaScript orchestriert: Scene Graph, UI, Netzwerk, DOM — überall dort, wo schnelle Iteration und Browser-Nähe zählen.
  • WebAssembly rechnet: kompilierter Bytecode mit vorhersagbarer Performance, ideal für Physik, Tracking, Mesh-Verarbeitung — und als Ziel für bestehende C/C++- und Rust-Bibliotheken.

WASM ersetzt JavaScript nicht. Es übernimmt die Hot Paths, für die das 16-ms-Framebudget (bei 90 Hz eher 11 ms) sonst zu eng wird.

Was seit 2023 passiert ist

WASM SIMD ist Baseline

SIMD (Single Instruction, Multiple Data) verarbeitet mehrere Datenpunkte pro Instruktion — genau das, was Matrix- und Vektorrechnung in XR permanent braucht. Alle großen Browser unterstützen WASM SIMD seit rund drei Jahren, und die Engines ziehen nach:

  • Godot 4.5 liefert Web-Exports nur noch mit aktiviertem SIMD aus. Die hauseigenen Benchmarks mit Jolt-Physik zeigen das realistische Bild: 1,5- bis 2-fache Performance in typischen Szenen — und in Stresstests, in denen die Physik-Engine ohne SIMD in den „spiral of death" aus einstelligen Frameraten kippt, bis zu 10–14-fache Resilienz. Letzteres ist keine rohe Rechenleistung, sondern Puffer gegen Framerate-Einbrüche — für XR genau der relevante Fall.
  • Wonderland Engine hat den Nicht-SIMD-Export komplett eingestellt — SIMD gilt inzwischen als gegeben.

Wasm 3.0 und WasmGC

Seit September 2025 ist WebAssembly 3.0 der lebende Standard. Die für XR relevanten Neuerungen:

  • WasmGC (in Chrome, Firefox und Safari längst default): Sprachen mit eigener Garbage Collection — Kotlin, Java, Dart, C# — kompilieren ohne mitgeschleppte GC-Runtime nach WASM. Das macht die Sprachwahl fürs Backend des XR-Cores deutlich freier.
  • Memory64: Adressraum jenseits der 4-GB-Grenze (im Web bis 16 GB). Relevant für große Pointclouds, Voxel-Daten oder CAD-Modelle.
  • JSPI (Phase 4, in Chrome 137+ und Firefox 139+): Synchroner WASM-Code kann asynchrone Web-APIs aufrufen — der Asyncify-Umweg mit seinem Overhead wird überflüssig.

WebGPU ist quer durch angekommen

Ende 2025 war es so weit: WebGPU läuft default in Chrome, Edge, Firefox (Windows ab 141, macOS ab 145) und Safari 26 — inklusive visionOS 26 auf der Vision Pro. Für XR zählen vor allem:

  • Native Compute Shader — Physik und Bildverarbeitung direkt auf der GPU
  • Multiview-Rendering — beide Augen in einem Pass statt doppeltem Draw-Call-Overhead
  • Deutlich geringerer CPU-Overhead pro Draw Call als bei WebGL — bei XR-Szenen mit vielen Objekten spürbar

WebGL 2 bleibt als Fallback die Baseline; die gängigen Engines und three.js handhaben den Wechsel inzwischen selbst.

Die Hardware-Seite

  • Meta Quest: Der Browser im Headset ist die vollständigste WebXR-Plattform — inklusive Handtracking und Passthrough-AR.
  • Apple Vision Pro: WebXR in Safari seit visionOS 2 default aktiv, mit visionOS 26 kommt WebGPU dazu.
  • Android: Chrome liefert WebXR-AR nativ.
  • Desktop-Chrome: WebXR weiterhin nicht default — zum Entwickeln und Testen bleibt der Immersive Web Emulator das Werkzeug der Wahl.

Wer liefert was: der Framework-Stand 2026

  • De-Panther WebXR Export: Der Unity-Weg ins Web lebt und wird gepflegt (zuletzt 0.25, Mai 2026; Unity 6 ab 6000.0.23f1). Unitys WebGL-Build ist ohnehin WASM + JS-Glue — das Paket ergänzt die WebXR-Device-API.
  • Needle Engine: Aktiv weiterentwickelt (Version 5 mit MaterialX- und OpenUSD-Support). Wichtig zu wissen: Needle kompiliert kein C# nach WASM, sondern ist eine TypeScript-Runtime auf three.js mit Unity- und Blender-Integration — WebXR, Multiplayer und AR für Quest, Vision Pro und Mobile inklusive.
  • Rogue Engine: Unity-ähnliche Umgebung auf three.js-Basis — und ein schönes WASM-Praxisbeispiel: Die Physik-Integration läuft über Rapier, eine in Rust geschriebene Engine, die nach WASM kompiliert wird.
  • Godot Web Export: WASM + SIMD default seit 4.5 — für kleine bis mittlere WebXR-Spiele der pragmatischste Weg.

Und ein ehrlicher Kassensturz: Mozilla Hubs — lange das Vorzeigeprojekt für social WebXR — wurde im Mai 2024 eingestellt. Der Code lebt als Community Edition weiter, aber das Projekt ist eine Mahnung: Ein solider WebXR-Stack ist keine Garantie für ein tragfähiges Produkt.

Bewährte Kombinationen aus der Praxis

Zwei Muster haben sich in meinen Projekten als tragfähig erwiesen.

Muster 1: three.js + WASM-Physik

Das Rendering bleibt in three.js (JavaScript), die Physik läuft als WASM-Modul — hier am realen Beispiel Rapier (Rust → WASM, die -compat-Variante lädt das WASM-Modul ohne Bundler-Konfiguration):

import * as THREE from 'three';
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
import RAPIER from '@dimforge/rapier3d-compat';

await RAPIER.init(); // WASM-Modul laden
const world = new RAPIER.World({ x: 0, y: -9.81, z: 0 });

const gltf = await new GLTFLoader().loadAsync('model.glb');
scene.add(gltf.scene);
// Rigid Bodies und Collider für die Meshes anlegen,
// dann pro Frame: world.step() + Mesh-Posen zurücklesen

Muster 2: Babylon.js + WASM-Berechnungskern

Klassisches Beispiel: Pathfinding oder Hand-Tracking-Auswertung pro Frame — zu teuer für JS, trivial für WASM. wasmModule steht hier für die instanziierten Exports eines WASM-Moduls (z. B. via WebAssembly.instantiateStreaming oder wasm-bindgen):

import { TransformNode, Vector3 } from '@babylonjs/core';

const actor = new TransformNode("actor", scene);

scene.onBeforeRenderObservable.add(() => {
  // calculatePath() liefert die nächsten Wegpunkte aus dem WASM-Kern
  const path = wasmModule.calculatePath(actor.position, target);
  actor.position = Vector3.Lerp(actor.position, path[0], 0.1);
});

Der Unity-Weg sieht ähnlich aus — hier ein kondensiertes Beispiel mit dem WebXR Export:

using UnityEngine;
using WebXR;

public class WebXRTest : MonoBehaviour
{
    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            WebXRManager.Instance.ToggleVR();
        }
    }
}

Wann lohnt WASM — und wann nicht

Lohnt sich für: Physiksimulationen, Mesh-Operationen, Tracking-Algorithmen, Decoder, CAD-Kerne — alles, was pro Frame messbar ins Budget frisst.

Nicht lohnend für: UI-Logik, Scene-Graph-Verwaltung, Event-Handling. Und Vorsicht bei der JS/WASM-Grenze: Aufrufe sind günstig, aber nicht gratis. Wer pro Frame pro Objekt über die Boundary geht, frisst den Gewinn oft wieder auf — besser gebündelte Calls auf Typed Arrays.

Faustregel aus der Praxis: erst den JS-Prototyp, Hot Paths im Profiler messen, dann gezielt portieren. Wer andersherum anfängt, optimiert blind.

Praxisnotizen

  • Threads brauchen Isolation: SharedArrayBuffer — und damit WASM-Threads — gibt es nur mit gesetzten COOP/COEP-Headern (cross-origin-isolated). Ohne sie läuft alles single-threaded.
  • Speicher getrennt denken: WASM hat explizite lineare Memory — allokieren und freigeben liegt beim Modul. Für große Datenblöcke zwischen beiden Seiten: SharedArrayBuffer oder übergebene Typed Arrays, nicht Objekt-Marshalling.
  • Assets sind der eigentliche Engpass: In den meisten WebXR-Projekten entscheidet nicht die CPU, sondern die Downloadgröße über Erfolg. Kompression (Draco, KTX2) und Streaming schlagen jeden Mikro-Benchmark.

Häufige Fragen

Kann man WebAssembly und JavaScript kombinieren?

Nicht nur kann — es ist die empfohlene Arbeitsweise: JS für UI/UX und schnelle Iteration, WASM für Physik-, ML- und CAD-Kerne. Beispiel: three.js Scene Graph + WASM-Physik.

Welche Frameworks unterstützen beide Seiten?

  • three.js (WASM-Module lassen sich direkt importieren; Rapier als Physik-Standard)
  • Babylon.js (native WASM-Plugins, integrierte WebXR-Unterstützung)
  • Unity WebGL (per WebXR Export) und Godot (Web-Export mit SIMD)

Wie sieht das Speichermanagement zwischen JS und WASM aus?

  1. SharedArrayBuffer für große Datenblöcke
  2. JS-seitige Garbage Collection für UI-Elemente
  3. WASM-Memory explizit allokieren und freigeben

Zwei Welten — ein Ziel

Die Zukunft der XR-Entwicklung liegt nicht in Entweder-oder-Entscheidungen, sondern im intelligenten Kombinieren beider Technologien. WebAssembly und JavaScript sind wie die beiden Hände eines Entwicklers — zusammen erreichen sie mehr als jede für sich. In meiner Arbeit hat sich gezeigt: Erst ihre Symbiose ermöglicht wirklich immersive Erlebnisse. Wer heute WebXR baut, bekommt mit WASM 3.0 und WebGPU ein Fundament, das vor drei Jahren noch Zukunftsmusik war.

Update September 2026: Dieser Artikel wurde überarbeitet — Stand von WASM-SIMD, Wasm 3.0/WasmGC, JSPI und WebGPU nachgezogen, nicht mehr zutreffende Referenzen (u. a. Mozilla Hubs) korrigiert und unbelegte Benchmarks entfernt.

Quellen


Wer ein WebXR-Projekt plant oder einen Performance-Engpass im bestehenden Stack hat: Nachricht an ingmar@konnow.de oder über LinkedIn — ein erster Blick auf die Architektur kostet nichts.

0%
6 Min. Lesezeit