Skip to content

Performance Guidelines

Open the editor to profile performance live.

These are practical targets, not hard engine limits. The runtime does not enforce budgets.

Frame Time

At 60 FPS you have ~16.6ms per frame. Clearing, grid, and primitives usually cost a little; most of the budget is your physics.

Suggested Object Counts

PrimitiveComfortableStress zoneNotes
particles≤ 500~2,000arc + fill each
lines≤ 1,000~3,000Path + stroke each
vectors≤ 200~500Line + arrowhead
circles≤ 300~1,000Arc + optional fill
arcs≤ 200~500Arc + stroke
bars≤ 100~500fillRect + label
text keys≤ 10~20Single HUD panel

TIP

Prefer fewer particles or shorter trails over exotic draw tricks. Cap arrays early.

dt Clamping

dt is capped at 0.05s. If the tab was idle for seconds, the next step is still at most 50ms — the sim slows rather than teleporting.

Optimization Patterns

Cap trails

javascript
state.trail.push({ x: state.x, y: state.y });
if (state.trail.length > 200) state.trail.shift();

Cull off-screen draws

javascript
const visible = state.particles.filter(
  (p) => p.x > -50 && p.x < w + 50 && p.y > -50 && p.y < h + 50
);

Pool particle objects

javascript
function spawn(x, y) {
  const p = state.pool.pop() || {};
  p.x = x; p.y = y;
  p.vx = (Math.random() - 0.5) * 100;
  p.vy = -100;
  p.life = 1;
  state.particles.push(p);
}

Measure FPS in the HUD

javascript
if (!state.fpsAccum) { state.fpsAccum = 0; state.fpsCount = 0; }
state.fpsAccum += dt;
state.fpsCount++;
if (state.fpsAccum >= 1) {
  state.lastFPS = state.fpsCount / state.fpsAccum;
  state.fpsCount = 0;
  state.fpsAccum = 0;
}

return {
  text: {
    FPS: (state.lastFPS ?? 0).toFixed(0),
    dt: (dt * 1000).toFixed(1) + 'ms',
  },
};

WARNING

If FPS drops, profile your loops first (distance checks, N² boids). Drawing is rarely the only bottleneck.

Memory

  • Unbounded state arrays grow forever — the engine never trims them.
  • A few hundred trail points is fine; tens of thousands can cause GC pauses.
  • The module registry is created once per compile — not a concern.

Keep arrays capped and recycle when spawning/despawning often.