Skip to content

feat: add an Async panel of loads, waits, fallbacks and chains - #30

Open
lxsmnsyc wants to merge 1 commit into
feat/timeline-panelfrom
feat/async-panel
Open

lxsmnsyc wants to merge 1 commit into
feat/timeline-panelfrom
feat/async-panel

Conversation

@lxsmnsyc

@lxsmnsyc lxsmnsyc commented Oct 24, 2026 •

Copy link
Copy Markdown
Member

Adds an Async tab that shows what the app is loading now, and how its async loads, waits and fallbacks went. This PR is based on #29.

async-detail

Changes

  • Loading now lists the async memos that are pending while the panel is open, with how long each has been loading and how many other nodes wait on them. It reads the reactivity graph, since the runtime sends no record when a load starts.
  • History lists, newest first:
    • Loads, from flight records. A load that a newer one replaced is flagged.
    • Waits, from hold records: what it waited on, the held writes, and the pending state the screen showed. A wait with nothing on screen, or a long tail, is flagged.
    • Fallbacks, from fallback records. One shown for less than 150ms is flagged as a flash.
    • Chains of loads that ran one after another, from attribution.history('waterfall'). The buffer is read on a microtask after each record, since the runtime stores a chain after the record of the load that ended it.
  • Records can be filtered by kind. The detail shows the action that started the record, and links loads and fallbacks to the reactivity graph and the ownership tree.
  • The copy button puts a Markdown report of the record on the clipboard. Held values with sensitive names are redacted.
  • Owner paths drop the toolbar's own owners, with the helper from the Issues panel.
  • The toolbar takes its own hold on the attribution engine when it mounts, so loads before the dock opens are kept.
  • The test fixture has a "show async" button that mounts a profile whose posts load waits for its user load, inside a Loading boundary.

A load that is still pending because its source has not landed yet also counts as loading now, since the graph marks it pending.

Testing

  • Unit tests in src/dev-toolbar/async/tracker.test.ts cover the history order, path trimming, chain dedupe, the limit, every flag and the reports.
  • A new e2e test mounts the profile, clicks the next user, checks the live list during the load, the load, fallback, chain and wait records, the wait detail, the filter, and the jump to the graph.
  • pnpm test, pnpm typecheck, pnpm format:check, pnpm build, pnpm check and the full e2e suite pass locally.

🤖 Generated with Claude Code

- An Async tab shows the async memos that are loading now, with how long each has been loading and how many nodes wait on them. The list comes from the reactivity graph while the panel is open.
- Its history lists loads, waits, fallbacks and chains of loads that ran one after another, from the attribution engine's flight, hold and fallback records and its waterfall history.
- Loads replaced by a newer load, waits with no pending state on screen or a long tail, fallbacks shown for less than 150ms, and chains are flagged.
- A record shows the action that started it, links to the reactivity graph and the ownership tree, and has a copy button for an agent report.
- Owner paths drop the toolbar's own owners, as the Issues panel does.
- The test fixture has a profile with two chained loads inside a Loading boundary.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.

1 participant