Skip to content

perf(ui): stub unused linkify-it and lift JS ceiling to 155 kB - #358

Merged
qte77 merged 1 commit into
mainfrom
perf/350-bundle-headroom
Nov 2, 2026
Merged

qte77 merged 1 commit into
mainfrom
perf/350-bundle-headroom

Conversation

@qte77

@qte77 qte77 commented Oct 29, 2026 •

Copy link
Copy Markdown
Owner

Closes #350

What

  • linkify-it → empty stub (ui/src/stubs/linkify-it.ts, aliased in ui/vite.config.ts). markdown-it, which @a2ui/react's Text renders through, constructs a LinkifyIt in its constructor but only calls it when linkify: true; @a2ui/react uses new MarkdownIt() (default preset, linkify off). Behaviour-neutral. If a future @a2ui/react turns linkify on, Text render throws and the e2e sweep catches it.
  • JS ceiling 150,000 → 155,000 B in check-bundle-size.mjs, per the issue's step 3. The measured reason is in docs/engineering-practices.md § Performance.

Numbers (clean npm ci && npm run build, node scripts/check-bundle-size.mjs)

JS gzip ceiling headroom
before (main @ 9e67ba0) 149,694 B 150,000 B 306 B
after 146,898 B 155,000 B 8,102 B

CSS is unchanged (5,872 / 8,000 B).

Why the ceiling moved and the bundle didn't shrink more

I measured the bundle with sourcemaps and stub builds that aren't committed:

  • The gate sums every emitted chunk, so lazy-loading the result sheet (the issue's step 2) moves bytes but creates no headroom.
  • Catalog pruning doesn't help: A2UIProvider calls ensureInitialized(), which registers the whole default catalog anyway.
  • zod is pinned by @a2ui/web_core's v0_8 schema, so we can't drop it.
  • The markdown-it stack is about 46 kB gzip (about 31% of the JS), mostly its entities decode table. The only way to reclaim it is to replace the markdown engine. That changes what model-authored text renders, and it changes the XSS surface behind dangerouslySetInnerHTML, so it's an owner decision, not a trim. Stubbing punycode.js would save about 1 kB but changes IDN link handling, so I left it alone.

Follow-ups for the owner (not in this PR)

  1. markdown-it is about 31% of the bundle. Options: replace the engine, or move to the @a2ui/react v0_9 entry, which takes a pluggable markdown renderer.
  2. The gate's header says "render-critical" but it sums lazy chunks too. If the intent is first-paint bytes, measuring only the entry would make lazy-loading a real lever.

Verification

  • ui: npm run lint (0 errors; the 9 warnings were already there) · npm run typecheck · npm test (82 passed) · npm run build · npm run size all pass locally.
  • A one-off vitest check (not committed) ran markdown-it inlined through this alias. It confirmed the stub is in use and that ### [Title](https://…), *caption*, the relative [Open →](?usecase=…) link and HTML escaping render as before.
  • npm audit --omit=dev --audit-level=high fails, on main too. These advisories appeared after the last green main run: dompurify (critical), markdown-it (high) and zod <4.6.6 (high). zod has no 3.x fix (GHSA-mrhx-c7xc-m3w5: first patched 4.6.6) and @a2ui/react pins zod ^3, so the ui job's audit step is red on every PR (dependabot chore(deps): Bump the npm-security group across 1 directory with 2 updates #349 too) until the owner decides on zod/a2ui. This PR doesn't touch package*.json.
  • The alias is verified on the production build path only. The vite dev path (dep pre-bundling) wasn't exercised here. The alias is root-relative and should resolve there too.
  • Live sweep: still to be checked after deploy. Deploying needs owner credentials. The change doesn't alter first-paint behaviour: same chunks, minus about 2.8 kB.

Changelog entry (to be collected in the lane's docs(changelog) PR)

Generated with Claude noreply@anthropic.com

markdown-it (via @a2ui/react) builds a LinkifyIt but never calls it with
the default preset, so alias it to an empty stub: 149,694 -> 146,898 B
gzip. The size gate sums every chunk, react-dom/zod/markdown-it are
outside our control, so the JS ceiling moves 150 -> 155 kB with the
measured breakdown recorded in docs/engineering-practices.md.

Closes #350

Co-Authored-By: Claude <noreply@anthropic.com>
@qte77
qte77 merged commit 6f51e51 into main Nov 2, 2026
10 of 11 checks passed
@qte77
qte77 deleted the perf/350-bundle-headroom branch November 2, 2026 15:34
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.

UI bundle has 306 B headroom under the 150 kB ceiling — trim before more UI

1 participant