Skip to content

perf: render static prose tags as native elements with baked-in classes - #34

Open
atinux wants to merge 1 commit into
mainfrom
perf/prose-native-elements
Open

perf: render static prose tags as native elements with baked-in classes#34
atinux wants to merge 1 commit into
mainfrom
perf/prose-native-elements

Conversation

@atinux

@atinux atinux commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

Summary

Long docs pages mount a Nuxt UI Prose* component instance for every paragraph, list item, table cell, and heading. This PR renders those static tags as plain HTML elements instead, with their Tailwind classes baked into the parsed tree, cutting per-node component instances from SSR, hydration, and client-side navigation.

How it works

  • New elements comark plugin (server/utils/comark-elements.ts): runs last in the parse pipeline and rewrites p, em, strong, hr, ul, ol, li, blockquote, inline code, the table family, and h1-h4 into final HTML with classes merged from the Nuxt UI prose theme + appConfig.ui.prose.* overrides, using the same tv({ extend: theme, ...override }) call the components make. It replicates component markup: table scroll-wrapper div, heading anchor links (per mdc.headings.anchorLinks) with the hash icon as a CSS mask, code color variants, cell alignment. pre subtrees are untouched (rangi owns them).
  • New proseElements map (app/utils/prose-elements.ts): passed to <MarkdownDocument :components>, mapping each tag to its own name so the renderer emits h('p') instead of resolving the global ProseP. Heading anchors use a prose-anchor tag mapped to 'a' so they do not resolve to ProseA.
  • ProseImg stays a component (zoom dialog) but is now lazily hydrated with hydrateOnVisible(): its chunk (the largest prose chunk, 5.2 KB) only downloads once an image scrolls into view.
  • Interactive prose stays as components: a, pre, callouts, tabs, code groups, etc. Children of native elements render normally, so in-content links keep SPA navigation.

Wiring

  • Plugin registered in server/utils/content.ts; CONTENT_PARSER_VERSION bumped to v3 (cached trees change shape).
  • Map spread into the docs page and landing page MarkdownDocument usages.
  • server/ added as a Tailwind source in modules/css.ts so the baked class literals stay covered even if they drift from the Nuxt UI theme.
  • tailwind-variants added as a direct dependency (the plugin cannot use @nuxt/ui/utils/tv: it imports #build/app.config, which is forbidden in nitro).

Impact

  • Total client bundle: unchanged (+1.1 KB gzip, the anchor-icon CSS rule).
  • Per docs page visit: 14+ prose chunk requests skipped (~7 KB gzip), ProseImg deferred until visible.
  • Main win: zero component instances, tv() calls, and useAppConfig proxies for ~19 tags during SSR, hydration, and every client-side navigation.

Trade-offs

  • appConfig.ui.prose.* overrides are applied at parse time and frozen into the cached tree (still respected, verified in tests, but runtime UTheme context overrides no longer affect these tags).
  • Theme class literals mirror Nuxt UI 4.11 and need a sync check when upgrading @nuxt/ui (noted in the plugin docblock).

Verification

  • 10 new unit tests (test/comark-elements.test.ts): class baking, app.config merging, author-class preservation, pre skip, table wrapper, heading anchors, alignment. Full suite: 164 passed.
  • nuxt typecheck clean, eslint clean (only pre-existing warnings).
  • SSR HTML diffed against the previous output on the playground: paragraph/list/table/code classes, heading anchor markup, ProseA link styling, and image zoom attributes are identical.

🤖 Opened by an AI coding agent (OpenCode) on behalf of @atinux, who reviewed the changes.

@vercel

vercel Bot commented Aug 26, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
comark-docs-layer Ready Ready Preview Aug 26, 2026 8:15am

@pkg-pr-new

pkg-pr-new Bot commented Aug 26, 2026

Copy link
Copy Markdown
npm i https://pkg.pr.new/comarkdown/comark-docs@34

commit: abf1f41

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