ONESHOTGEMS

For game developers

Find memory that grows after a scene should end

A browser game can appear healthy for one round and still retain objects each time a level restarts. Detached interface nodes, forgotten event listeners, animation callbacks, and references to old scene data can keep memory reachable. A single heap measurement is noisy and cannot prove a leak; look for a repeatable pattern after equivalent sessions and confirm that suspected objects remain referenced after their intended lifetime ends.

Repeat one lifecycle on purpose

Capture a baseline after loading, play the same short level, return to the menu, and repeat that exact route several times. Use browser memory tools to compare snapshots taken at the same point after cleanup and garbage collection when the tooling allows it. Look for growing counts of a specific object type, such as scene nodes, rather than reacting to total memory alone.

Run the test once with developer tools closed and once open if measurement itself appears to change behavior. The useful signal is whether the same classes and retained paths accumulate across cycles, not whether one snapshot has a larger number than another machine's.

Give every scene an explicit teardown

When a scene ends, cancel its pending animation frame, stop timers, remove listeners registered on longer-lived targets, and clear collections that hold its entities. Keep references to callbacks so they can be removed, or group related listeners under an AbortController and abort the group at teardown.

Test the boundary: enter and exit a scene, trigger the old input action, and confirm that the previous scene no longer reacts. Also verify that any cached assets are intentionally shared or released; indiscriminate cleanup can cause needless reloads, while accidental ownership can keep a large scene alive.

Questions about browser game memory leak

Does memory going up prove a leak?

No. Browsers reserve memory and collect objects on their own schedule. A leak is more credible when equivalent lifecycle repeats retain progressively more instances through a path your code still holds.

Can removing an event listener help cleanup?

Yes, when a longer-lived target holds a callback that closes over scene data. MDN documents removeEventListener() and also describes passing an AbortSignal so a group of listeners can be removed together.

Sources and further reading

Report a correction · How these guides are made

Follow your curiosity