Skip to content

perf(playground): stop bundling monaco-editor alongside the CDN copy - #756

Draft
dgaponov wants to merge 1 commit into
mainfrom
seo/defer-monaco
Draft

perf(playground): stop bundling monaco-editor alongside the CDN copy#756
dgaponov wants to merge 1 commit into
mainfrom
seo/defer-monaco

Conversation

@dgaponov

@dgaponov dgaponov commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

Оба редактора плейграундов импортировали значения из пакета monaco-editor ради двух констант KeyCode/KeyMod в одной строке. Импорт значения затягивает весь пакет в бандл, а @monaco-editor/react и так качает Monaco с jsDelivr — то есть за редактор платили дважды.

Коды клавиш теперь берутся из инстанса monaco, который onMount передаёт вторым аргументом, остальное стало import type.

/libraries/charts/playground, прод-сборка, чистый профиль: свой JS 2094 → 1347 КБ (−36%), всего 3054 → 2307 КБ. CDN-часть не изменилась — это настоящий редактор. Исчезли чанки на 2.0 МБ и 216 КБ; "First Load JS" не изменился, потому что они асинхронные.

Обёртка в next/dynamic уже была на месте — дублирующая копия в бандле и была реальной потерей.

Не проверял вручную, что Cmd/Ctrl+Enter применяет изменения: редактор монтируется без ошибок, но нажатие не эмулировал.

🤖 Generated with Claude Code

Both playground editors imported values from the `monaco-editor` package:

    import {KeyCode, KeyMod, type editor} from 'monaco-editor';

Only KeyCode and KeyMod are runtime values, used on a single line to register
Cmd/Ctrl+Enter. Everything else from that import is type-only. But importing
any value pulls the whole package into the bundle, and @monaco-editor/react
already downloads Monaco separately from jsDelivr at runtime, so every
playground visit paid for Monaco twice.

Take the key codes from the monaco instance that onMount already receives and
make the remaining import type-only, which erases at compile time.

Measured on /libraries/charts/playground, production build, fresh browser
profile with an empty cache on both sides:

    first-party JS   2094 kB -> 1347 kB   (-747 kB, -36%)
    CDN JS            960 kB ->  960 kB   (unchanged, this is the real editor)
    total JS         3054 kB -> 2307 kB   (-24%)

Two chunks disappear: a 2.0 MB (515 kB transferred) monaco chunk and a
216 kB sibling. Route "First Load JS" is unchanged because these were async
chunks loaded when the playground component mounts, not part of the entry.

Note the audit's suggested fix — wrapping Monaco in next/dynamic — was already
in place: every playground is dynamically imported with ssr: false and
rendered conditionally per libId. The duplicate bundled copy was the actual
waste.

Verified in a browser: the Monaco editor and the chart still render on the
charts playground, the editor and graph canvas still render on the graph
playground with no console errors, and all five playground routes return 200.
Build, lint and typecheck pass. E2E not run - Playwright browsers are not
installed locally.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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