Skip to content

Template: Performance investigation

Status: Reference

Task

Investigate a performance issue: lag on <surface> (e.g. tab switching, chip taps, scrolling, mutation feedback).

Pre-implementation checks

  1. Reproduce mentally: what's the user actually doing? Walk through the JS-thread work that happens between the user's action and the visual response.
  2. Read the related rebuild-log entries: grep "Phase 12\|Phase 13" docs/rebuild-log.md. Past phases addressed many perf concerns. Don't re-investigate fixed issues.
  3. Check existing perf docs:
    • docs/architecture/agentic-project-foundation.md (master plan)
    • docs/architecture/networking-foundation-plan.md (Phase 14)
    • docs/architecture/drift-prevention.md (enforcement strategy)
  4. Identify the suspected layer:
    • Animation thread blocked — Tamagui driver, MotionPressable, PillNav indicator
    • Render-time JS work — heavy useMemo, hook waterfalls, conditional mount of expensive children
    • Subscription cascades — broad invalidateQueries, signalKeys.all style fan-outs
    • Hydration races — Zustand _hasHydrated issues, AsyncStorage timing
    • Component re-renders — provider chain, unstable references, prop identity

Investigation pattern

  1. Audit the suspect surface:
    • Read every hook fired on its mount
    • Count synchronous work in render
    • Look for unstable prop identities (inline objects, fresh fns)
  2. Confirm the bottleneck before fixing:
    • "I think it's X" → grep for X, count call sites
    • Don't propose fixes for unconfirmed bottlenecks
  3. Reference industry patterns:
    • For tab/chip lag: useDeferredValue (React 18), Moti driver, sliding indicator
    • For waterfalls: useQueries, ensureQueryData, normalize cache
    • For renders: React.memo, stable refs, lift state up
  4. Avoid stop-gap fixes: prefer architectural fixes that prevent the class of problem.

Files in scope (typical)

  • The screen/component reported as lagging
  • Provider chain (apps/mobile/app/_layout.tsx)
  • Relevant primitives (packages/ui/src/pill-nav.tsx, motion-pressable.tsx)
  • Animation config (apps/mobile/tamagui.config.ts)
  • Realtime / signal hooks if subscription-related

Files OUT of scope

  • Unrelated optimizations
  • Speculative future optimizations not directly addressing the report

What you produce

A concise report (under 800 words):

  1. Bottleneck identification: specific file:line, what's happening, why it's slow
  2. Industry-canonical fix: with citation if possible (TanStack docs, React docs, Reanimated docs, published research)
  3. Implementation plan: concrete files + changes
  4. Validation criteria: how we know the fix worked
  5. What's left if this fix doesn't solve it: the next layer to investigate

Hard constraints

  • AOR-3: 5+ file edits → use the full Research → Plan → Delegate → Verify → Commit → Doc workflow (WORKFLOW)
  • AOR-2: don't refactor while you're there (SCOPE)
  • STYLE-2: animation driver is @tamagui/animations-moti (UI thread) — Tamagui pressStyle is now safe; don't add MotionPressable wrappers unless you need fine-grained Reanimated worklet control
  • Past phases shipped many perf fixes; don't undo them. Read docs/rebuild-log.md first.

Post-implementation verification

bash
git status
yarn run check
yarn workspace @twomore/web build &
yarn workspace @twomore/mobile preflight &
wait

What to report

  • Bottleneck (specific file:line)
  • Fix (specific changes)
  • Industry/research source (with URL)
  • Validation results
  • What's left if more lag persists

Markdown remains the source of truth. Run yarn docs:check before handoff.