React re-render optimization, Three.js rendering performance, useMemo/useCallback patterns, bundle size reduction, and 60fps profiling
Applies when building performance-sensitive features, optimizing re-renders, reducing draw calls, minimizing bundle size, fixing memory leaks, profiling bottlenecks, or implementing game loops.
React.memo, useMemo, useCallback used deliberately after profilinguseState for per-frame updatesimport() by route/feature; React.lazy + SuspenseuseMemo with stable depsbudget.json)budget.json)| Metric | Target | |---|---| | Performance score | ≥ 90 | | LCP | < 2.5 s | | TTI | < 3.5 s | | CLS | < 0.1 | | Initial JS gzipped | < 500 KB |
import { memo, useCallback, useMemo } from 'react';
interface HUDProps {
score: number;
health: number;
onPause: () => void;
}
function GameHUDInner({ score, health, onPause }: HUDProps): JSX.Element {
const healthColor = useMemo(() => (health > 50 ? '#0f0' : '#f00'), [health]);
const handlePause = useCallback(() => onPause(), [onPause]);
return (
<div className="hud">
<span>Score: {score}</span>
<span style={{ color: healthColor }}>Health: {health}%</span>
<button onClick={handlePause}>Pause</button>
</div>
);
}
export const GameHUD = memo(GameHUDInner);
import { useRef } from 'react';
import { useFrame } from '@react-three/fiber';
import * as THREE from 'three';
function Spinner(): JSX.Element {
const mesh = useRef<THREE.Mesh>(null);
useFrame((_, delta) => {
if (mesh.current) mesh.current.rotation.y += delta;
});
return <mesh ref={mesh}><boxGeometry /><meshStandardMaterial /></mesh>;
}
const ORIGIN = [0, 0, 0] as const;
function At(): JSX.Element {
return <mesh position={ORIGIN}><sphereGeometry /></mesh>;
}
import { lazy, Suspense } from 'react';
const HelpOverlay = lazy(() => import('./HelpOverlay'));
function App(): JSX.Element {
return (
<Suspense fallback={null}>
<HelpOverlay />
</Suspense>
);
}
// BAD: useState in useFrame — 60 re-renders/sec
useFrame(() => setRotation(r => r + 0.01));
// BAD: new object every render
<mesh position={[0, 0, 0]}>…</mesh>
// BAD: unmemoized expensive calc inside render
const sorted = data.sort((a, b) => a - b);
// BAD: importing entire lodash
import _ from 'lodash';
// BAD: forgetting to dispose geometry / material / texture
setInterval / subscriptions → cleanup in useEffect returnTHREE.Geometry / Material / Texture → dispose on unmountremoveEventListener in cleanupuseRef or restructureuseState in useFrame; 60 Hz updates use refsInstancedMesh used for > 10 similar objectsbudget.json) after changesSearch for places (restaurants, cafes, etc.) via Google Places API proxy on localhost.
Interact with GitHub using the `gh` CLI. Use `gh issue`, `gh pr`, `gh run`, and `gh api` for issues, PRs, CI runs, and advanced queries.
Create or update AgentSkills. Use when designing, structuring, or packaging skills with scripts, references, and assets.
Start voice calls via the OpenClaw voice-call plugin.
Notion API for creating and managing pages, databases, and blocks.
Gemini CLI for one-shot Q&A, summaries, and generation.
Category:developer