Ein Web-Spiel ausliefern, das schnell lädt (eine praktische Checkliste)
Wenn Spieler nicht in Sekunden loslegen können, springen sie ab. Dieses Tutorial ist eine praktische Checkliste, die du auf fast jeden Web-Spiel-Stack anwenden kannst (Canvas/WebGL/WebGPU, Pixi/Three/PlayCanvas, eigene Engine und so weiter).
1) Erst Budgets setzen (sonst kannst du nicht optimieren)
Wähle Budgets, die zu deinem Zielgerät passen. Ein solider Standard für ein Sofort-Spielerlebnis:
- Ausgeliefertes JS+CSS: unter ~300–500 KB gzip (kleiner ist besser)
- Kritische Assets vor der ersten Eingabe: unter ~2–5 MB komprimiert
- Zeit bis zur ersten Eingabe: unter ~3–5 Sekunden auf einem Mittelklasse-Handy
Schreib sie auf und behandle sie wie API-Verträge.
2) Das Richtige messen
In den Chrome DevTools:
- Nutze Performance, um eine Sitzung aufzuzeichnen und lange Tasks zu untersuchen.
- Nutze Network, um zu prüfen:
- Übertragungsgröße gegen dekodierte Größe
- Caching-Header
- ob Assets progressiv streamen oder als ein riesiger Klumpen ankommen
In Spielbegriffen verfolgst du:
- die Zeit bis "kann sich der Spieler bewegen?"
- die Zeit bis zum "ersten sinnvollen Frame"
- die "Latenz der ersten Eingabe" (Eingabe bis Frame)
Dein Gespür für die Eingabelatenz entspricht heute einer Standardmetrik: Interaction to Next Paint (INP) hat im März 2024 First Input Delay als Core Web Vital abgelöst und misst die volle Zeit von der Eingabe bis zum nächsten Frame über alle Interaktionen hinweg, nicht nur die erste. Ziel ist ein INP unter 200 ms im 75. Perzentil, ein nützlicher externer Maßstab für die Reaktionswerte, die du ohnehin verfolgst.
3) Komprimiere alles, was geht
Stell sicher, dass dein Hosting ausliefert:
- Brotli (
br) für Textassets (JS/CSS/HTML/WASM), wo verfügbar - gzip als Rückfalloption
Wenn Host und CDN es unterstützen, ist Zstandard (zstd) inzwischen eine dritte Option für Content-Encoding. Es steckt in Chrome und Edge ab 123, Firefox ab 126 und Safari ab 26.3 (rund 80 % der Nutzer) und erreicht Brotli-nahe Raten bei geringerer Server-CPU-Last, was bei großen WASM- und JSON-Payloads hilft. Browser bewerben Accept-Encoding: zstd nur über HTTPS, halte also Brotli und gzip als Rückfall für alle anderen konfiguriert.
Bei WebAssembly-Builds ist Kompression oft der Unterschied zwischen "sofort" und "lädt nie".
4) Lade nicht die ganze Welt im Voraus
Teile dein Spiel auf in:
- Boot: minimaler Loader, Eingabe und erste Szene
- Core: die zentralen Gameplay-Systeme
- Optional: weitere Level, Kosmetik, hochauflösende Texturen, Bonus-Audio und so weiter
Lade "Optional" erst, wenn:
- der Spieler schon spielen kann, und/oder
- du weißt, dass er diese Inhalte will (etwa weil er ein Menü oder Level erreicht hat)
5) Die richtigen Asset-Formate wählen
Für die meisten Web-Spiele:
- Bilder: nimm WebP (oder AVIF, wenn du langsameres Encoding verkraftest) für UI und Hintergründe.
- Audio: nimm Ogg Vorbis für den allgemeinen Fall, teste AAC für das Apple-Ökosystem.
- Video: nimm MP4/H.264 für Kompatibilität, WebM, wo es unterstützt wird und kleiner ist.
Behalte die Dekodierkosten im Blick: "kleinerer Download" kann trotzdem "langsamer zu dekodieren" heißen.
6) Halte die erste Szene klein und berechenbar
Vermeide in deiner ersten interaktiven Szene:
- Stürme von Shader-Kompilierungen
- riesige Textur-Uploads
- prozedurale Generierung, die den Haupt-Thread blockiert
- synchrones JSON-Parsen von Megabyte-Klumpen
Speziell bei Texturen liefere KTX2 mit Basis-Universal-Superkompression statt PNG oder JPEG aus. Sie bleibt nach dem Upload GPU-komprimiert (beim Laden transkodiert zu BC7 auf dem Desktop oder ASTC auf Mobilgeräten), was das VRAM um das 4- bis 8-Fache senkt und Uploads weit günstiger macht, als ein volles PNG zu dekodieren und rohe Pixel auf die GPU zu schieben.
Wenn du schwere Arbeit erledigen musst, dann:
- verteilt über mehrere Frames, oder
- in einem Worker (wo möglich)
7) Aggressiv cachen (aber richtig)
Nutze langlebiges Caching für inhaltsadressierte Assets:
Cache-Control: public, max-age=31536000, immutable
Für HTML-Einstiegspunkte hältst du das Caching kurz, damit du Updates sicher ausrollen kannst.
8) Mach Fehlschläge schnell und lesbar
Wenn etwas schiefgeht, zeig:
- eine klare Fehlermeldung
- einen Button zum erneuten Versuch
- einen Link zum Melden des Problems
Stille Fehlschläge zerstören Vertrauen.
9) Wenn du Wasm-Threads nutzt, versteh COOP/COEP
Hängt dein Build von SharedArrayBuffer ab (bei manchen Wasm-Threading-Setups üblich), brauchst du sehr wahrscheinlich Header für Cross-Origin-Isolation:
Cross-Origin-Opener-Policy: same-originCross-Origin-Embedder-Policy: require-corp
Beim COEP-Header hast du zwei Möglichkeiten. require-corp ist die strenge Variante, verlangt aber, dass jedes Cross-Origin-Asset (CDN-Texturen, Drittanbieter-Skripte) einen Cross-Origin-Resource-Policy-Header sendet, sonst wird es blockiert. Cross-Origin-Embedder-Policy: credentialless schaltet SharedArrayBuffer und Cross-Origin-Isolation ebenfalls frei, lädt Cross-Origin-Ressourcen aber ohne Zugangsdaten, statt ihre Zustimmung per CORP zu verlangen. Wenn du Assets von einem CDN ziehst, das du nicht kontrollierst, ist credentialless meist der weniger schmerzhafte Weg.
Teste früh auf deinem echten Host, denn Header und Drittanbieter-Embeds können vieles kaputt machen.
10) Mach es ohne SDK spielbar
Wenn du auf Cinevvas Creator-Workflow zielst, streb an:
- eine URL, die zuverlässig startet
- keine Pflichtanmeldung, um eine Demo zu starten
- vorhersehbare Steuerung
Dann bist du bereit für den Vertrieb, ohne zusätzliche SDKs einzubinden.
Verwandt:
- Für Spiele-Creator
- Richtlinie zu KI-generierten Inhalten
- Streaming von Assets — Muster für progressives Laden bei großen Spielen
- Service Worker fürs Spiel-Caching — Assets für sofortige Wiederbesuche cachen
- Web-Game-Engines im Vergleich — Build-Größen und Ladezeiten der Engines
- Wie du dein Spiel auf itch.io veröffentlichst — Browser-Spiele für itch.io-Embeds optimieren