AgentSkillsCN

rezi-perf-profiling

对Rezi应用的性能进行剖析与优化。在应用运行缓慢、帧率下降,或渲染阶段耗时过长时使用。

SKILL.md
--- frontmatter
name: rezi-perf-profiling
description: Profile and optimize Rezi app performance. Use when app feels slow, frames drop, or render phases take too long.

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 timing
  • packages/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 hooks
  • packages/bench/src/ — profiling scripts

Steps

  1. Enable profiling and run:

    bash
    REZI_PERF=1 REZI_PERF_DETAIL=1 node your-app.js
    
  2. Observe phase timings: view → commit → layout → render → build

  3. Run systematic profiling:

    bash
    npx tsx packages/bench/src/profile-phases.ts
    npx tsx packages/bench/src/profile-construction.ts
    
  4. Apply common fixes:

    BottleneckFix
    View phase slowctx.useMemo(() => expensiveComputation, [deps]) for expensive computations
    Commit phase slowAdd key props on list items for stable reconciliation
    Layout phase slowReduce nesting depth; layout stability signatures skip relayout when tree is stable
    Render phase slowUse ui.virtualList() for large datasets
    Animation-heavy screen slowLimit transition scope (properties), animate only visible rows, avoid per-frame object churn
    Overall slowFlatten unnecessary wrapper nodes
  5. Depth guardrails:

    • Warning at 200 levels
    • Fatal at 500 levels
    • Refactor deep nesting into flatter structures

Key optimization patterns

  • ctx.useMemo(() => expensiveComputation, [deps]) — skip recomputation
  • key on every list item — enables O(1) reconciliation
  • ui.virtualList() — only renders visible rows
  • useStagger(...) + ui.virtualList(...) — stagger only the visible window
  • ui.box({ transition: { properties: [...] } }) — animate only required dimensions
  • Avoid creating new closures/objects in render — use ctx.useCallback(fn, [deps])