Skip to content

perf(artifacts): mount the shell frame with the detail route so the shell downloads once, before the row arrives - #30

Merged
fforres merged 1 commit into
skywardfrom
perf/artifact-frame-early
Oct 18, 2026
Merged

fforres merged 1 commit into
skywardfrom
perf/artifact-frame-early

Conversation

@fforres

@fforres fforres commented Oct 18, 2026

Copy link
Copy Markdown

Why

On a cold cache the artifact page downloaded the shell document twice. The <link rel="prefetch"> added when the renderer chunk resolved was still in flight when the iframe mounted, after the artifact row arrived. Chrome does not merge an in-flight prefetch with a later iframe navigation, so the frame started its own request.

In a Playwright run against a local server, a COMPLETED top-frame prefetch was reused by the iframe. The in-flight case is what doubled the request. In prod the shell is 664 KB gzip, so the prefetch is likely still running when the row arrives.

What changes

  • The frame mounts early: ArtifactStage mounts with the detail route, before the row resolves. The renderer takes code: string | null, where null means the row is still loading. The shell iframe starts downloading right away, and the source is delivered through the existing bridge once both the bridge is initialized and the row has arrived, exactly once per frame.
  • Remount only on a new source: the iframe key is a generation counter. It bumps only when a later source replaces an earlier one, so the first source does not remount the frame, and a code change still does.
  • A failed row fetch replaces the stage with the existing ErrorState, so no booted frame is left visible. The single loading cover and the rendered signal are unchanged.
  • Prefetch removed: the prefetch link, its dedupe set and the shellHtmlUrl plumbing are gone.

Tests

  • New scenario artifact-shell-single-download: fresh browser context, the row delayed by 1.5 s, every shell request counted. It asserts one request, started before the row finishes.
    • New code: 3 runs pass, each with 1 request, starting about 1.23 s before the row finished.
    • Old code: fails with 2 requests.
  • Existing selfhost scenarios artifact-loading-surface, artifacts and artifact-source-roundtrip pass.
  • Unit, typecheck, oxlint and oxfmt are clean on the touched packages.
  • Not run on cloud: the new scenario ran only on selfhost.

https://claude.ai/code/session_019ZE3j9YzRKxT4LaiDCBv6S

…hell downloads once, before the row arrives

The artifact page used to add a prefetch hint for the shell document and then mount the frame after the row loaded, which made two downloads of the largest asset. The frame now mounts as soon as the route renders, boots while the row is fetched, and receives the source over the existing bridge. A failed row replaces the stage with the error state, so no booted frame stays behind.

Adds a scenario that asserts one shell request on a cold cache, started before the row response completes.

Claude-Session: https://claude.ai/code/session_019ZE3j9YzRKxT4LaiDCBv6S
@fforres
fforres merged commit 8100544 into skyward Oct 18, 2026
4 of 40 checks passed
@fforres
fforres deleted the perf/artifact-frame-early branch October 18, 2026 08:29
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