Skip to content

[docs-infra] Lazy-load react-runner + sucrase for demo live-edit#48586

Open
brijeshb42 wants to merge 2 commits into
mui:masterfrom
brijeshb42:lazy-react-runner
Open

[docs-infra] Lazy-load react-runner + sucrase for demo live-edit#48586
brijeshb42 wants to merge 2 commits into
mui:masterfrom
brijeshb42:lazy-react-runner

Conversation

@brijeshb42
Copy link
Copy Markdown
Contributor

@brijeshb42 brijeshb42 commented May 28, 2026

Convert ReactRunner and DemoEditor from static imports to React.lazy() in Demo.tsx. The live-edit code path (react-runner pulling all of sucrase, plus react-simple-code-editor) only runs after the user focuses/hovers the demo editor — liveDemoActive defaults to false on every demo.

Prefetch both chunks on hover (and on keyboard focus into the demo card) so the runtime is already cached by the time the user actually clicks edit: preloadDemoEditor() and preloadReactRunner() hold cached promises that are also passed to React.lazy(), so a single dynamic import is shared between the prefetch path and the render path.

We could also prefetch these chunks on idle (if desired).

Some page-wise data
Page JS gzip master JS gzip PR JS gzip Δ JS decoded master JS decoded PR JS decoded Δ
/ 767.5 KB 627.7 KB −139.8 KB 2660.2 KB 2108.9 KB −551.4 KB
/material-ui/getting-started/installation/ 553.8 KB 485.5 KB −68.3 KB 1914.7 KB 1634.7 KB −280.0 KB
/material-ui/react-button/ 570.7 KB 523.6 KB −47.1 KB 1999.5 KB 1786.2 KB −213.3 KB
/material-ui/react-text-field/ 597.7 KB 550.0 KB −47.7 KB 2155.1 KB 1941.8 KB −213.3 KB
/material-ui/react-autocomplete/ 827.5 KB 779.4 KB −48.1 KB 3368.2 KB 3154.9 KB −213.4 KB
/material-ui/react-table/ 847.9 KB 807.2 KB −40.7 KB 2929.8 KB 2738.8 KB −191.0 KB
/material-ui/react-dialog/ 589.7 KB 541.2 KB −48.4 KB 2070.1 KB 1856.7 KB −213.4 KB
/system/getting-started/custom-components/ 573.8 KB 529.2 KB −44.6 KB 1960.9 KB 1755.9 KB −205.0 KB

CSS unchanged: 10.0 KB gzip / 80.7 KB decoded on both.

CSS unchanged.
Extra chunk size loaded on hover/edit - 50.6 kB transferred 210 kB resources

Existing live-edit functionality preserved: hovering the demo warms the chunks; clicking "expand" opens the source viewer; focusing the textarea swaps the bundled component for ReactRunner with the edited code.

On hold till #47821 lands

@brijeshb42 brijeshb42 added the scope: docs-infra Involves the docs-infra product (https://www.notion.so/mui-org/b9f676062eb94747b6768209f7751305). label May 28, 2026
@brijeshb42 brijeshb42 force-pushed the lazy-react-runner branch 2 times, most recently from 62de9f4 to 9b4a388 Compare May 28, 2026 09:55
@code-infra-dashboard
Copy link
Copy Markdown

code-infra-dashboard Bot commented May 28, 2026

Deploy preview

https://deploy-preview-48586--material-ui.netlify.app/

Bundle size

Bundle Parsed size Gzip size
@mui/material 0B(0.00%) 0B(0.00%)
@mui/lab 0B(0.00%) 0B(0.00%)
@mui/private-theming 0B(0.00%) 0B(0.00%)
@mui/system 0B(0.00%) 0B(0.00%)
@mui/utils 0B(0.00%) 0B(0.00%)

Details of bundle changes


Check out the code infra dashboard for more information about this PR.

@brijeshb42 brijeshb42 marked this pull request as ready for review May 28, 2026 10:13
@brijeshb42 brijeshb42 requested review from a team and Copilot May 28, 2026 10:13
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Defers loading of react-runner (and its sucrase dependency) and DemoEditor (with react-simple-code-editor) by switching them from static imports to React.lazy() with cached dynamic-import promises. The chunks are prefetched on demo hover/focus so they’re ready by the time the user actually engages with live edit, while the existing SSR/bundled component continues to render via Suspense fallbacks. Per the PR data this trims ~50 KB gzip / ~200 KB decoded from docs pages.

Changes:

  • Replace static DemoEditor/ReactRunner imports with React.lazy backed by cached preloadDemoEditor() / preloadReactRunner() helpers.
  • Wrap ReactRunner in <Suspense fallback={BundledComponent}> and DemoEditor in <Suspense fallback={null}>; add BundledComponent to the live-component memo deps.
  • Prefetch both chunks from Root's onMouseEnter/onFocus so the runtime is warmed before live-edit activation.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@brijeshb42 brijeshb42 force-pushed the lazy-react-runner branch 2 times, most recently from 6f0206a to 70bbbbe Compare May 28, 2026 11:00
Convert ReactRunner and DemoEditor from static imports to React.lazy() in
Demo.tsx. The live-edit code path (react-runner pulling all of sucrase,
plus react-simple-code-editor) only runs after the user focuses the demo
editor — `liveDemoActive` defaults to false on every demo.

Wrap the lazy components in React.Suspense:
- ReactRunner suspense fallback = the pre-rendered BundledComponent so the
  demo stays visible while the live runtime loads on first edit.
- DemoEditor suspense fallback = null (mounts inside an opened Collapse).

Prefetch both chunks on hover (and on keyboard focus into the demo card) so
the runtime is already cached by the time the user actually clicks edit:
`preloadDemoEditor()` and `preloadReactRunner()` hold cached promises that
are also passed to React.lazy(), so a single dynamic import is shared
between the prefetch path and the render path.

Verified via the next.js build-manifest (497 pages total):
- 0 / 497 pages statically pull the sucrase chunk (12669)
- 0 / 497 pages statically pull the DemoEditor lazy chunk (26770)
  (next.js still auto-prefetches DemoEditor on idle; sucrase only loads on
  hover or first edit)

Per-page bundle diff vs deploy-preview-48584 (which already has the rtl
lazy fix), measured on /material-ui/react-button/:

| chunk           | local raw  | deploy raw | Δ raw      |
|-----------------|------------|------------|------------|
| 47094 sucrase   | not loaded | 208.3 KB   | -208.3 KB  |
| 22072 Demo      | not loaded | 49.7 KB    |  -49.7 KB  |
| 77240, 14134    | not loaded | 40.1 KB    |  -40.1 KB  |
| 50613 Demo'     | 45.7 KB    | not loaded |  +45.7 KB  |
| 26770 DemoEditor| 11.3 KB    | not loaded |  +11.3 KB  |
| 7317, 63073     | 31.7 KB    | not loaded |  +31.7 KB  |
| net per page    |            |            | -214.8 KB  |

Net per page: -214.8 KB raw / -49.1 KB gzip.

Existing live-edit functionality preserved: hovering the demo warms the
chunks; clicking "expand" opens the source viewer; focusing the textarea
swaps the bundled component for ReactRunner with the edited code.
@brijeshb42 brijeshb42 force-pushed the lazy-react-runner branch from 70bbbbe to 70e16fd Compare May 28, 2026 11:06
@brijeshb42 brijeshb42 added the on hold There is a blocker, we need to wait. label May 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

on hold There is a blocker, we need to wait. scope: docs-infra Involves the docs-infra product (https://www.notion.so/mui-org/b9f676062eb94747b6768209f7751305).

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants