Repository navigation
Conversation
The code component loads the Mermaid chart with lazy(), but it imports
the block's download and fullscreen controls statically, and the
fullscreen control imports the chart to render it full screen. That
chain puts the chart, pan-zoom, the SVG utilities and both controls in
the main bundle, and the chart's lazy chunk is a one-line re-export of
it. Every app pays for Mermaid's UI whether or not it renders a diagram.
Move the whole block (header, controls and chart) into
lib/mermaid/block.tsx and load it with a single lazy() behind the same
Suspense boundary. The resolved markup and the controls are unchanged.
Loading is not: the first diagram on a page now downloads the block's
chunk before the chart starts rendering, and the existing code block
skeleton covers that wait. The skeleton is shorter than the 200px the
chart reserves, as it already was.
A new test bundles an app that imports only Streamdown from the built
package with esbuild (through tsup, with code splitting) and checks
that the chart, the fullscreen view and the block controls are
reachable only through import(). It fails on main.
Sizes in KiB, gzip level 9, measured on tsup output before postbuild
adds "use client" (the normal build is slightly larger; the up-front
savings are the same). The app's entry is
`import { Streamdown } from "streamdown"; export { Streamdown };`
with React external and every other dependency bundled. Up front is
the entry and its static imports.
main this change
Rolldown 1.1.5 (esm, minify)
up front 148.18 143.52
block chunk - 5.76
esbuild 0.27.2 via tsup 8.5.1
(esm, splitting, minify)
up front 156.94 151.93
deferred 0.44 6.31
This package's build
index.js and its static imports 27.94 22.90
block chunk - 5.98
The code component no longer needs its cognitive-complexity
suppression, so it goes.
Contributor
|
@xyrolle is attempting to deploy a commit to the Vercel Team on Vercel. A member of the Team first needs to authorize it. |
This was referenced Oct 16, 2026
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
The code component lazy-loads the Mermaid chart, but it imports the block's download and fullscreen controls statically, and the fullscreen control imports the chart. That chain keeps the chart, pan-zoom, the SVG utilities and both controls in the main bundle, so the lazy boundary has no effect. This PR moves the whole block into
lib/mermaid/block.tsxand loads it with a singlelazy().The resolved markup and the controls are unchanged. Loading does change: the first diagram on a page now downloads the block's chunk before the chart starts rendering, and the existing code block skeleton covers that wait. The skeleton is shorter than the 200px the chart reserves, as it already is on
main.Type of Change
Related Issues
Fixes #679
Related to #668, which changes how the same component handles errors from partial charts, and #490, which asks for controls integrated with the host.
Changes Made
lib/mermaid/block.tsx(new) renders the block: header, controls and chart, moved from the code component without changes.lib/components.tsxlazy()inside the sameSuspense.__tests__/mermaid-bundle-boundary.test.ts(new), with its helper__tests__/built-consumer.ts:Streamdownfrom the built package with esbuild (through tsup, with code splitting).import().pnpm buildfirst, as CI already runs..changeset/lazy-mermaid-block.md(patch).Testing
The new test fails on
mainand passes with the change:Full run on this branch:
Test Coverage
The boundary test covers the built package. The existing Mermaid component, download, fullscreen and pan-zoom suites cover the block's behaviour, unchanged.
Bundle size
All sizes are KiB, gzip level 9, measured on tsup output before
postbuildadds"use client". The normal build is slightly larger, and the up-front savings are the same.import { Streamdown } from "streamdown"; export { Streamdown };, with React external and every other dependency bundled. "Up front" means the entry and its static imports.maindist/index.jsand its static importsScreenshots/Demos
N/A
Checklist
pnpm changeset)Changeset
Additional Notes
A failed chunk download still escapes to the host's error boundary, as it does on
mainfor the chart's lazy import, and the chart'serrorComponentcan't handle a failure before its module loads.