name: rezi-perf-profiling description: Profile and optimize Rezi app performance. Use when app feels slow, frames drop, or render phases take too long. user-invocable: true allowed-tools: Read, Glob, Grep, Bash(REZI_PERF=1 REZI_PERF_DETAIL=1 ), Bash(npx tsx packages/bench/) argument-hint: "[performance-concern]" metadata: short-description: Performance profiling
When to use
Use this skill when:
- App feels slow or unresponsive
- Frames drop or input lags
- Need to identify which render phase is the bottleneck
- Optimizing a specific widget or screen
Source of truth
packages/core/src/app/widgetRenderer.ts— render pipeline with phase timingpackages/core/src/runtime/commit.ts— reconciliation (leaf/container reuse)packages/core/src/layout/— layout engine (FNV-1a stability signatures)packages/core/src/widgets/composition.ts— animation utility hookspackages/bench/src/— profiling scripts
Steps
Enable profiling and run:
REZI_PERF=1 REZI_PERF_DETAIL=1 node your-app.jsObserve phase timings: view → commit → layout → render → build
Run systematic profiling:
npx tsx packages/bench/src/profile-phases.ts npx tsx packages/bench/src/profile-construction.tsApply common fixes:
Bottleneck Fix View phase slow ctx.useMemo(() => expensiveComputation, [deps])for expensive computationsCommit phase slow Add keyprops on list items for stable reconciliationLayout phase slow Reduce nesting depth; layout stability signatures skip relayout when tree is stable Render phase slow Use ui.virtualList()for large datasetsAnimation-heavy screen slow Limit transition scope ( properties), animate only visible rows, avoid per-frame object churnOverall slow Flatten unnecessary wrapper nodes Depth guardrails:
- Warning at 200 levels
- Fatal at 500 levels
- Refactor deep nesting into flatter structures
Key optimization patterns
ctx.useMemo(() => expensiveComputation, [deps])— skip recomputationkeyon every list item — enables O(1) reconciliationui.virtualList()— only renders visible rowsuseStagger(...)+ui.virtualList(...)— stagger only the visible windowui.box({ transition: { properties: [...] } })— animate only required dimensions- Avoid creating new closures/objects in render — use
ctx.useCallback(fn, [deps])