Skip to content

feat(performance-monitor-plugin): add startup insights tab#283

Open
burczu wants to merge 4 commits into
callstackincubator:mainfrom
burczu:feat/performance-monitor-startup-insights
Open

feat(performance-monitor-plugin): add startup insights tab#283
burczu wants to merge 4 commits into
callstackincubator:mainfrom
burczu:feat/performance-monitor-startup-insights

Conversation

@burczu
Copy link
Copy Markdown
Contributor

@burczu burczu commented May 20, 2026

Resolves #250 — Add startup insights to the performance monitor plugin.

Summary

  • derive-startup-summary.ts — new UI-side derivation function that takes SerializedPerformanceReactNativeMark[] and returns a typed StartupSummary: the three known phases (nativeLaunch, runJSBundle, initialMount) plus any unknown *Start/*End pairs, each with a status of complete | in-progress | missing, a startTime, and a duration. The total entry is anchored on nativeLaunchStart and uses the last complete phase's end time as its upper bound, so it degrades gracefully when e.g. initialMount is absent. Lives alongside the existing derive-startup-phases.ts which continues to feed the Measures tab unchanged.

  • StartupTab.tsx — scorecard layout component. Renders a Total startup row at the top (no bar — it is the 100% reference) followed by a row per phase with a proportional bar whose width is phase.duration / total.duration * 100%. Missing phases render "—" in muted gray; in-progress phases render "In progress…" in italic gray with no bar. Empty state ("Start a session to see startup data") shown when the session has not been started and no marks have arrived. No TanStack/Virtuoso — there are only 4–N rows, so a simple Box with map is appropriate.

  • App.tsx — imports StartupTab and inserts it as the first tab (defaultValue="startup"). All existing tabs are unchanged.

  • Startup data comes from React Native's buffered native marks (nativeLaunchStart/End, runJSBundleStart/End, initialMountStart/End). The PerformanceObserver is already subscribed with buffered: true, so marks emitted before "Start Session" is clicked are replayed on subscribe and the Startup tab populates immediately without any extra instrumentation in the app.

  • Computation is UI-side (consistent with the existing derive-startup-phases.ts pattern). No new wire events or RN-side changes.

Test plan

  • pnpm --filter @rozenite/performance-monitor-plugin test run — 40/40 pass
  • pnpm --filter @rozenite/performance-monitor-plugin typecheck — clean
  • pnpm --filter @rozenite/performance-monitor-plugin lint — clean
  • Playground (pnpm --filter playground ios or :android) → Performance Monitor in DevTools:
    • First tab is now Startup (previously Measures)
    • Click Start Session — Startup tab immediately shows Native Launch, JS Bundle, and Initial Mount with durations and proportional bars (buffered marks replay on subscribe)
    • Total row shows a sensible summed duration
    • Bar widths are visually proportional — longest phase has the widest bar
    • Navigating to Measures / Metrics / Marks / RN Marks / Resources tabs still works (regression)
    • Stop Session then Start Session — Startup tab clears and repopulates correctly
    • Missing phase scenario: if a phase mark pair is absent, its row shows "—" with no bar and Total still computes from available phases

New test surface

  • src/ui/__tests__/derive-startup-summary.test.ts (14 tests) — all three phases complete (correct durations + total), incomplete pair (Start without End → in-progress, startTime recorded), missing phases (missing status, total missing when nativeLaunchStart absent), unknown *Start/*End pairs appended after known phases, total uses last complete phase end when initialMount absent, out-of-order mark stream still pairs correctly.

burczu added 4 commits May 20, 2026 07:16
Computes a StartupSummary from raw React Native marks: the three known
phases (nativeLaunch, runJSBundle, initialMount) plus any unknown
Start/End pairs, each with a status of complete/in-progress/missing,
and a total duration anchored on nativeLaunchStart.
New first-position Startup tab shows Total startup time plus Native
Launch, JS Bundle, and Initial Mount phases with proportional bars.
Missing phases render as "—", in-progress phases as "In progress…".
Empty state shown when no session has been started.
@burczu burczu force-pushed the feat/performance-monitor-startup-insights branch from 0b7ca3e to fff834c Compare May 20, 2026 05:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add startup insights to the performance monitor plugin

1 participant