Agent skill
performance
Apply performance optimization patterns for game loop, rendering, and state updates. Use when discussing frame rate, optimization, profiling, or when editing core game loop code. Auto-apply when user mentions "slow", "fps", "lag", or "performance".
Stars
163
Forks
31
Install this agent skill to your Project
npx add-skill https://github.com/majiayu000/claude-skill-registry/tree/main/skills/data/performance
SKILL.md
Performance Optimization Skill
This is a real-time game requiring 60fps. Apply these patterns for performance-critical code.
Performance Budget
| Operation | Budget | Notes |
|---|---|---|
| Full frame | 16ms | 60fps target |
| Physics update | 2-4ms | Wave simulation |
| Rendering | 8-10ms | Canvas draw calls |
| UI updates | 2-3ms | React reconciliation |
| Overhead | 2ms | GC, browser, etc. |
Game Loop Patterns
RequestAnimationFrame
javascript
function gameLoop(timestamp) {
const deltaTime = timestamp - lastTimestamp;
lastTimestamp = timestamp;
update(deltaTime);
render();
requestAnimationFrame(gameLoop);
}
Fixed Time Step (for physics)
javascript
const PHYSICS_STEP = 1000 / 60; // 16.67ms
let accumulator = 0;
function update(deltaTime) {
accumulator += deltaTime;
while (accumulator >= PHYSICS_STEP) {
physicsUpdate(PHYSICS_STEP);
accumulator -= PHYSICS_STEP;
}
}
Memory Optimization
Object Pooling
javascript
// Pre-allocate reusable objects
const foamRowPool = [];
function getFoamRow() {
return foamRowPool.pop() || createFoamRow();
}
function releaseFoamRow(row) {
foamRowPool.push(row);
}
Typed Arrays
javascript
// Use for numeric data
const grid = new Float32Array(width * height);
const indices = new Uint16Array(count);
Avoid Allocation in Hot Paths
javascript
// Bad - creates new object every frame
function update() {
const vec = { x: 0, y: 0 };
}
// Good - reuse scratch objects
const scratchVec = { x: 0, y: 0 };
function update() {
scratchVec.x = 0;
scratchVec.y = 0;
}
Canvas Rendering Optimization
Batch Draw Calls
javascript
// Bad - many small paths
for (const segment of segments) {
ctx.beginPath();
ctx.moveTo(segment.x1, segment.y1);
ctx.lineTo(segment.x2, segment.y2);
ctx.stroke();
}
// Good - single path
ctx.beginPath();
for (const segment of segments) {
ctx.moveTo(segment.x1, segment.y1);
ctx.lineTo(segment.x2, segment.y2);
}
ctx.stroke();
Layer Canvases
javascript
// Static background on separate canvas
const bgCanvas = document.createElement('canvas');
// Only redraw when needed, composite over game canvas
Avoid State Changes
javascript
// Bad - changes style every iteration
for (const item of items) {
ctx.fillStyle = item.color;
ctx.fillRect(item.x, item.y, item.w, item.h);
}
// Good - group by style
const byColor = groupBy(items, 'color');
for (const [color, items] of byColor) {
ctx.fillStyle = color;
for (const item of items) {
ctx.fillRect(item.x, item.y, item.w, item.h);
}
}
Profiling
Browser DevTools
- Performance tab: flame chart, frame timing
- Memory tab: heap snapshots, allocation timeline
In-Code Timing
javascript
const start = performance.now();
expensiveOperation();
console.log(`Operation: ${performance.now() - start}ms`);
Performance Tests
javascript
// src/render/foamRendering.perf.test.js
it('renders under 16ms budget', () => {
const start = performance.now();
renderFoam(testData);
expect(performance.now() - start).toBeLessThan(16);
});
Common Pitfalls
- GC Pressure: Creating objects in game loop
- Layout Thrashing: Reading/writing DOM in alternation
- Unthrottled Events: Mouse/touch events firing faster than frames
- Unnecessary Work: Recalculating unchanged values
Reference Plans
plans/tooling/128-react-performance-optimization.mdplans/bugfixes/130-bathymetry-heatmap-performance.mdplans/perf-test-separation.md
Didn't find tool you were looking for?