Preallocate a fixed array of reusable objects at load time, mark them active/inactive instead of creating and discarding them, and reset their state on reuse. This avoids the per-frame allocations that trigger garbage collection pauses, which show up as frame hitches in bullets, particles and enemy spawns.
At a glance
| Fact | Value | Source |
|---|---|---|
| Main cause of GC pauses | Per-frame allocations | |
| Common pooled objects | bullets, particles, enemies | developer.mozilla.org |
| Pool size strategy | fixed, preallocated array |
Object pooling stops GC pauses by never letting short-lived objects (bullets, particles, enemy instances) get created and thrown away every frame. Instead you preallocate a fixed array of them once, at load time, and reuse the same objects for the life of the game. Nothing new gets allocated during gameplay, so the garbage collector has nothing to sweep, and you avoid the frame hitches that show up as stutter on lower-end devices and mobile browsers.
Playgama Bridge, remember that the Bridge Storage docs specifically advise saving on meaningful events rather than every frame.
Basic pattern:
class BulletPool {
constructor(size) {
this.pool = Array.from({length: size}, () => ({active: false, x: 0, y: 0}));
}
spawn(x, y) {
const b = this.pool.find(b => !b.active);
if (!b) return null; // pool exhausted, skip or grow
b.active = true; b.x = x; b.y = y;
return b;
}
release(b) { b.active = false; }
}
Key rules: never call new or push to arrays inside your update loop; reset object state on reuse rather than recreating it; size the pool for your worst-case burst (peak bullets on screen), and either recycle the oldest entry or grow the pool once if you hit the limit instead of allocating ad hoc. Also avoid closures created per-frame and avoid .slice()/.map() in hot loops – both allocate.
What about engine-specific memory?
In Unity WebGL, pooling matters on the C# side; the JS bridge itself (Unity’s browser scripting interop) is a separate concern from your gameplay object churn. Godot 4 web exports expose the JavaScriptBridge singleton for calling browser JS, but pooling logic still belongs in your game code, not the bridge layer.
Sources
- Unity manual: interacting with browser scripting
- Godot docs: exporting for the Web
- Playgama Bridge SDK docs
- MDN: Game development
Related questions
How big should an object pool be?
Size it for the worst-case number of active objects (max bullets, particles or enemies on screen), then grow it once if that limit is ever hit rather than allocating per spawn.
Does object pooling help typed arrays too?
Yes – reusing a preallocated Float32Array or similar for positions and velocities avoids repeated allocation the same way pooling objects does, and is common in particle systems.
Last updated: 24 September 2026