Skip to content

perf: cache the artifact shell, minify its inner renderer, and prefetch it early - #26

Merged
fforres merged 3 commits into
skywardfrom
perf/artifact-shell-cache
Oct 18, 2026
Merged

fforres merged 3 commits into
skywardfrom
perf/artifact-shell-cache

Conversation

@fforres

@fforres fforres commented Oct 18, 2026

Copy link
Copy Markdown

Why

Opening an artifact downloaded the MCP-Apps shell document again on every view: it is about 4.7 MB raw (about 950 KB gzip), and hashed assets were served with max-age=0, must-revalidate and no ETag. On a cold open the download also waited for the artifact row, because the iframe mounts only after the row arrives.

What changes

  • host-cloudflare: a build-only plugin emits _headers. /assets/* (content-hashed) becomes public, max-age=31536000, immutable. The stable-named shell copy read by the MCP session keeps revalidating.
  • mcp-apps-shell: bundleInnerRenderer minifies in production. The shell drops from 4,720,043 B to 2,733,014 B raw, and from 968,294 B to 755,385 B gzip. The smoke harness stays unminified.
  • react: preloadArtifactRenderer adds one <link rel="prefetch"> for the shell document once the renderer chunk resolves. The shell module exports shellHtmlUrl, so the document download overlaps the row fetch. packages/react still does not import the shell package.

Tests

  • artifact-renderer.test.tsx: one prefetch link per URL, and none when no URL is announced.
  • vite.test.ts passes.
  • Typecheck and oxlint are clean for the touched packages.

https://claude.ai/code/session_019ZE3j9YzRKxT4LaiDCBv6S

@fforres
fforres merged commit 763df5d into skyward Oct 18, 2026
4 of 40 checks passed
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