WebGL Browser Games: From Prototype to Deployment
A client arrives with a Unity prototype: the game runs perfectly in the editor, but after building to WebGL, the browser throws Out of Memory or the loading takes 30 seconds. According to Google's study, 40% of users leave a page if load time exceeds 3 seconds. WebGL has 256 MB of memory by default, one thread, no file system access, and Safari with its quirks. We have been developing WebGL games turnkey since 2014—over 10 years of experience and more than 50 projects: hyper-casual games for marketing, educational simulators, interactive 3D presentations. Our experience shows: without deep optimization, the project won't run for half of the audience. We help you go from prototype to deployment, ensuring stable performance on all target browsers.
How WebGL Differs from a Native Build
Memory — The Main Constraint
Unity WebGL compiles C# to WebAssembly via IL2CPP and runs everything in a single browser thread. The browser allocates a linear heap at startup — 256 MB by default. Exceeding this limit leads to Out of Memory and a page crash.
In practice, this means:
- All assets loaded via Resources.Load or Addressables live in the same memory pool alongside the wasm code and stack.
- Textures need aggressive compression: ETC2 and ASTC are not supported in WebGL — only DXT (Desktop) and PVRTC (Safari/iOS, with caveats). We use crunch compression + a fallback to uncompressed for Safari.
- An AudioClip in WAV format is 40 MB. The same clip in Vorbis (OGG) is 3 MB — that's a factor of 13 smaller. In the context of a 256 MB heap, this is critical.
For projects with large content volumes, we switch to a 512 MB limit via PlayerSettings.WebGL.memorySize, but remember: this reserves memory immediately on page load, regardless of actual usage. Reducing draw calls by 30% through batching and occlusion culling also lowers memory pressure.
How to Tackle the WebGL Memory Limitation
Lack of Multithreading and Workarounds
WebAssembly threading requires SharedArrayBuffer, which is blocked on most hosts without proper CORS headers (Cross-Origin-Opener-Policy: same-origin + Cross-Origin-Embedder-Policy: require-corp). In practice, we only enable threading if we control the server.
Without threading, all tasks—physics, animations, audio decoding—run on the main thread. This constraint forces a different architectural approach:
- Coroutines with yield instead of heavy Update() loops — spreads computations across frames.
- The Burst Compiler works in WebGL even without threading — it compiles hot paths into SIMD-optimized wasm, reducing execution time by 20–40%.
- Algorithms with O(n²) complexity that go unnoticed on PC will kill framerate in the browser.
How to Reduce Build Size and Loading Time
A standard Unity WebGL build without optimization weighs 30–60 MB (gzip). Users wait for loading and leave. We optimize:
- Managed Stripping Level: High — removes unused .NET code. Saves 5–15 MB.
- IL2CPP Code Generation: Faster runtime for production (slower compilation, faster runtime).
- Brotli compression instead of gzip — the server must support Content-Encoding: br. Brotli is 20% better than gzip, reducing file sizes further.
- Addressables for assets — load only what's needed for the current scene, the rest on demand.
Real case: a hyper-casual game for a marketing campaign. Initial build — 48 MB gzip. After stripping, texture optimization, and splitting into Addressable bundles — 11 MB initial load, remaining assets loaded in the background. Time to first gameplay dropped from 18 to 4 seconds — that's 4.5 times faster. Hosting cost savings of 40% due to less traffic.
| Optimization | Effect |
|---|---|
| Code Stripping High | 5–15 MB saved |
| Brotli compression | 20% size reduction vs gzip |
| Addressables | 50% load time reduction |
| Crunch texture compression | 50% memory reduction |
Why a WebGL Game Might Not Work on Safari
Safari implements WebGL differently from Chrome and does not support threading. Additionally, memory management differs: on iOS, the WebGL context can be dropped when resources are low. We test on real devices using BrowserStack and LambdaTest to ensure compatibility. Contact us for a WebGL project audit — we will identify bottlenecks and propose solutions.
What Our Work Includes (Deliverables)
- Requirements analysis and target browser definition (2–3 days)
- Asset architecture with Addressables groups
- Development and optimization for WebGL with guaranteed memory and performance
- QA on real devices (Safari, Chrome, mobile)
- Deployment with correct MIME types and CDN setup
- Full project documentation (configurations, build pipelines, manual)
- Access to source code and build repositories
- Post-launch support (1 month bug fixes included)
- Training for your team on WebGL maintenance
Stack and Tools
Engine: Unity current LTS, URP (Built-in pipeline is undesirable for WebGL — legacy). ShaderGraph with limitations: some nodes do not translate correctly to WebGL GLSL; we verify via Preview in the editor.
Browser interaction: JavaScript plugins via jslib files in Assets/Plugins/WebGL/. Call JS from C# using [DllImport("__Internal")]. Call C# from JS using SendMessage() or Module.dynCall. For complex integrations (OAuth, payment systems, analytics), we write custom JS wrappers over Unity.
Multiplayer in WebGL: WebSocket instead of UDP. Mirror with SimpleWebTransport — works over WSS. Photon Fusion supports WebGL via WebSocket relay. Latency is higher than UDP, so we account for it in the design.
Analytics and ads: UnityAds for WebGL works via iframe. For custom analytics, we call directly through jslib to Google Analytics / Amplitude. Firebase SDK in WebGL — only Firebase Analytics and Firestore (Auth and Realtime Database limited).
Browser Compatibility
| Browser | WebGL 2.0 | Threading | Notes |
|---|---|---|---|
| Chrome 100+ | Yes | Yes (with COOP/COEP) | Best support |
| Firefox 100+ | Yes | Yes (with COOP/COEP) | Good support |
| Safari 15+ | Yes | No | Memory quirks |
| Edge (Chromium) | Yes | Yes (with COOP/COEP) | Same as Chrome |
| Mobile Chrome | Yes | No | GPU throttling in background |
| Mobile Safari | Partial | No | Many limitations |
We test on real devices. BrowserStack or LambdaTest — for automation.
Development Process
- Requirements analysis (2–3 days). Determine: target browsers, memory requirements, if multiplayer is needed, integration with external services (auth, payments, analytics). A WebGL project starts with constraints, not features.
- Asset architecture. Plan Addressable Groups from the start — which assets in the initial build, what gets loaded on the fly. Mistake: adding Addressables mid-project — it requires refactoring all asset loading paths.
- Development and optimization. Alongside development, regular builds and size measurement via Build Report. Unity Profiler works for WebGL through a Development Build and remote profiling from the editor.
- QA on target platforms. Mandatory: real mobile Safari, real Chrome on an Android mid-range device. DevTools emulators do not reflect actual memory consumption and GPU throttling.
- Deployment. Nginx with correct MIME types (.wasm → application/wasm, .data → application/octet-stream) and Brotli/gzip. CDN for static assets — loading assets from an edge node instead of origin significantly reduces time to first frame.
Timelines — from 1–2 weeks for simple casual games up to 2 months for mid-core projects with multiplayer and complex integration. The cost is calculated individually after analyzing the technical specifications. We guarantee a stable build and provide a free initial consultation. Contact us — we will evaluate your project for free and propose the optimal development strategy.





