Godot Web Performance: What Actually Costs You in the Browser
Godot Web Performance: What Actually Costs You in the Browser
Honesty note: all numbers below that say “my build” are from my real Godot demo export (measured here) — ~40.5MB raw / 12.3MB gzip. The rest is Godot’s documented web behavior as of 4.x/2026.
TL;DR
- Web performance is load-time-first. On mobile connections the browser game’s first enemy is the download: my Godot demo shipped ~40.5MB raw (12.3MB gzip) — at 2MB/s that’s ~6s of pure download before a single frame, and gzip only helps once (the numbers).
- Threads change the story — with a hosting condition. Godot’s threaded web build uses
SharedArrayBuffer, which browsers allow only under cross-origin isolation (COOP/COEP headers, no ads/third-party scripts on the page). 4.3+ offers single-threaded export — no SAB, runs anywhere, but core-bound performance drops (export warnings). - The runtime budget is the same everywhere: fewer draw calls, smaller textures, no per-frame allocations. Godot’s renderer batches and culls for you, but oversized textures still cost GPU memory and fill rate — compress them.
- The honest frame: for a casual H5 game, Godot web is “load-heavy but fine once running.” If your game is simple enough to not need Godot’s power, the engine weight is pure cost — that’s why I moved to Phaser (my reasoning).
The load-time math (where 90% of pain lives)
| Item | My Godot demo | Note |
|---|---|---|
| index.wasm | 37.68MB raw / 9.77MB gzip | The engine — can’t strip without custom compile |
| index.pck | 2.51MB | Your assets |
| index.js | 0.27MB | Bootstrap |
| Total | ~40.5MB raw / 12.3MB gzip | First-load story |
What this means: even gzipped, ~12MB crosses the wire before the game starts. On a 3MB/s mobile connection that’s ~4s of loading screen; on a congested 1MB/s it’s 12s+. The engine weight is a load-time tax you pay every session.
Mitigations that actually work:
- Host on a CDN / fast origin (Cloudflare-class) — the bytes are the same, the latency isn’t (where I host).
- Texture compression + size audit — the .pck grows with your assets; compress before you ship (asset sizes).
- gzip/brotli at the server — Godot’s docs and templates assume it; make sure your host sends it.
- Single-thread export when you don’t need threads — avoids the SAB/hosting requirement (see below) and trims some complexity.
Threads: the performance lever with a hosting condition
Godot’s threaded web build parallelizes work across cores — real gains on desktop, less on mobile. The catch:
- Browsers require cross-origin isolation for
SharedArrayBuffer:Cross-Origin-Opener-Policy: same-origin+Cross-Origin-Embedder-Policy: require-corp. - Isolation means no ads, no third-party embeds, no CDN-hosted external scripts on the page hosting the game — a hard clash with ad-supported portal hosting (my SDK reality).
- Godot 4.3+ defaults to single-threaded export to avoid this: runs anywhere, simpler hosting, at a performance cost for thread-heavy workloads. For a casual game the single-thread cost is usually invisible.
Decision rule: want threads → own the hosting (no ads on the game page) and send the headers. Ads on the page → single-thread export. (full warnings)
Runtime costs (what happens after the load)
Once running, Godot web is a normal engine with the usual budget:
- Draw calls — Godot batches 2D sprites; the cost rises with unbatched draws and particle systems.
- Texture memory — oversized PNGs/JPEGs cost GPU memory and fill rate; atlas + compress (the 60fps budget).
- Scripting — GDScript is interpreted; hot loops in GDScript are slower than C# — move tight per-frame loops to C# or nodes when they matter.
- GC and allocations — same rule as everywhere: no per-frame allocations (memory reality).
The honest verdict for casual H5 games
Godot web in 2026 is powerful but heavy: the 40MB-class first load and the threading/hosting condition are real taxes, while the runtime itself is fine for most 2D games once loaded. For a casual web game whose needs are below Godot’s power ceiling, that weight is pure cost — which is my documented reason for building in Phaser (the size story) while still recommending Godot to code-first developers targeting desktop or complex web games.
Pitfalls
- Measuring only “it runs” — first-load bytes and seconds are the browser game’s core metric; measure them (how).
- Threads without headers — black screen/
SharedArrayBuffer is not defineduntil you send COOP/COEP; or use single-thread export (warnings). - Threads + ads on the same page — cross-origin isolation forbids it; pick one.
- Raw PNGs into the .pck — texture compression is free win; audit asset sizes (guide).
- GDScript in hot loops — fine for game logic, costly for per-frame heavy math; use C# or design around it.
Bottom line
Godot web performance is a load-time story first: my demo’s ~40.5MB raw (12.3MB gzip) engine is a first-session tax, threads are powerful but demand cross-origin-isolated (ad-free) hosting, and runtime costs are the usual engine budget. If your game fits Godot’s power, it’s great; if it doesn’t need it, the weight is the cost — the calculation that moved my own H5 build to a minimal engine (why).