Optimizing JavaScript Performance for Browser Games

470 views 2 replies

Collected some performance tips from profiling our HTML5 canvas game. Sharing the biggest wins:

Memory & GC

  • Object pooling — pre-allocate bullets, particles, enemies. Avoid new in the game loop at all costs.
  • Typed arraysFloat32Array for positions/velocities is faster than regular arrays
  • Avoid string concatenation in hot paths — use template literals or arrays

Rendering

  • OffscreenCanvas for background layers that don't change every frame
  • requestAnimationFrame with delta time, never setInterval
  • Batch draw calls — sort sprites by texture atlas before drawing

The single biggest win was object pooling — eliminated GC pauses that were causing frame drops every ~5 seconds.

Good list — one addition that made a surprisingly large difference for us: moving the game loop itself into a Web Worker with OffscreenCanvas. Decoupling the simulation and render tick from the main thread means GC pauses and DOM activity (ads, analytics, whatever) stop spiking your frame time.

The setup is more involved than it sounds — you need to transferControlToOffscreen() and message-pass input events from the main thread — but once it's wired up, frame pacing becomes dramatically more consistent. We went from occasional 40ms spikes to a much flatter profile on mid-range hardware.

Also worth profiling: canvas.getContext('2d') vs WebGL even for 2D games. If you're doing a lot of image blitting with transforms, WebGL sprite batching can be a significant win over the 2D context API, especially on mobile where the GPU is underutilized and the CPU is the bottleneck.

Object pooling is absolutely the #1 optimization. I'd also add: avoid closures in hot loops. They create hidden allocations that the GC has to clean up.

Another overlooked one: use Math.trunc() instead of Math.floor() for pixel snapping — it's measurably faster in V8.

Moonjump
Forum Search Shader Sandbox
Sign In Register