Skip to content

Back to projects

WebGL

Perceived load time in a browser-based 3D game

· 6 min

A 3D action game running entirely in the browser via WebGL has to balance two competing goals: loading enough audio and three-dimensional models to feel complete, while still feeling ready to play almost the instant the page opens.

Illustration of a play button with a progress bar

Audio blocking the start of the game

In an earlier version, every weapon sound file was loaded eagerly during scene initialization, before the player had interacted with anything at all. That added a slice of network time to how long it took the game to feel ready, and ran into a common browser restriction anyway: an audio context can't start without a user gesture, so part of that eager loading wasn't even serving its purpose.

Deferring loading to the player's first gesture

Audio loading was deferred until the player's first click or tap. That solved both problems at once: time-to-feels-ready dropped, since that loading left the critical path, and the loading now lined up exactly with the moment the browser would allow audio to start anyway.

3D models: show something now, swap it later

The game's weapons were initially built from simple primitive geometry only, quick to assemble, but visually thin. The latest version takes a hybrid approach: it builds and shows a cheap simplified version of each weapon immediately, and loads the real 3D model in the background, swapping the provisional one out the moment loading finishes. If the real model fails to load, the game just keeps the simplified version instead of stalling or leaving a hole in the scene.

What's still missing

Not all of the planned 3D content has this on-demand loading applied yet, some models still exist only as uncompressed files in the project, waiting to be wired up the same way. It's a reminder that this kind of loading budget needs to be watched as more content gets added, not solved once and forgotten.

The result

Without relying on any FPS metric, the effect is noticeable: the game reaches a playable state faster and never sits blocked on the network before the player has done anything, the remaining wait happens in parallel, while the player is already playing on a provisional version.