perf(web): load Shiki language grammars lazily instead of in the eager core chunk - #3496
Open
fanzeyi wants to merge 1 commit into
Open
perf(web): load Shiki language grammars lazily instead of in the eager core chunk#3496fanzeyi wants to merge 1 commit into
fanzeyi wants to merge 1 commit into
Conversation
…r core chunk ## Related issue N/A ## Summary - The `manualChunks` guard that keeps Shiki in one chunk (to avoid a cyclic import crash — the language-index ↔ alias-map split that throws "Cannot read properties of undefined (reading 'flatMap')" and blanks the Monaco/file viewer) matched both `/shiki` and `/@shikijs/`. That also swept every `@shikijs/langs/<lang>` grammar — which Shiki loads via dynamic import as per-language chunks — into the single, eagerly `modulepreload`ed core chunk. So ~200 language grammars (~1.68 MB gzip) were downloaded on every initial page load, even though a session uses only a few languages. - Exclude `@shikijs/langs/<lang>` from the `shiki` chunk so grammars stay lazy per-language chunks. Keep Shiki's core, engines, and bundle glue together so the cyclic core stays intra-chunk — the engines must stay too: excluding them re-splits the cycle across chunks and reintroduces the `flatMap` crash. - Initial-load eager JS drops from ~11.8 MB to ~4.37 MB (Shiki 1.68 MB → 466 KB gzip); grammars become 427 on-demand chunks. Layout-independent (same result under pnpm hoisted and isolated). ## Test Plan - `pnpm --filter web run build` succeeds. - Verified the emitted `shiki` chunk statically imports only the rolldown runtime (no cross-chunk cycle) and contains `bundledLanguagesAlias` co-located with its reader — under both hoisted and isolated node_modules. - Verified per-language grammar chunks (python, rust, typescript, …) are emitted separately and are NOT `modulepreload`ed by `index.html`. - Recommended pre-merge smoke test: open the file viewer / Monaco editor and a markdown code block and confirm syntax highlighting renders. ## Demo N/A ## Type of change - [ ] Bug fix - [ ] Feature - [ ] UI / frontend change - [x] Refactor / chore - [ ] Docs - [ ] Test / CI - [ ] Breaking change ## Test coverage - [ ] Unit tests added / updated - [ ] Integration tests added / updated - [ ] E2E tests added / updated - [x] Manual verification completed - [x] Existing tests cover this change - [ ] Not applicable ## Coverage notes Verified via build output analysis: the `shiki` core chunk is acyclic with the alias map co-located (cycle fix preserved), and language grammars are emitted as separate, non-preloaded chunks. Existing Shiki/code-block tests exercise the runtime highlighting path; this change only affects chunk grouping, not module behavior. ## Changelog Faster initial load — syntax-highlighting language grammars now load on demand instead of all upfront. Signed-off-by: Zeyi (Rice) Fan <zeyi.f@databricks.com>
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.
Related issue
N/A
Summary
manualChunksguard that keeps Shiki in one chunk (to avoid a cyclicimport crash — the language-index ↔ alias-map split that throws "Cannot read
properties of undefined (reading 'flatMap')" and blanks the Monaco/file
viewer) matched both
/shikiand/@shikijs/. That also swept every@shikijs/langs/<lang>grammar — which Shiki loads via dynamic import asper-language chunks — into the single, eagerly
modulepreloaded core chunk.So ~200 language grammars (~1.68 MB gzip) were downloaded on every initial
page load, even though a session uses only a few languages.
@shikijs/langs/<lang>from theshikichunk so grammars stay lazyper-language chunks. Keep Shiki's core, engines, and bundle glue together so
the cyclic core stays intra-chunk — the engines must stay too: excluding them
re-splits the cycle across chunks and reintroduces the
flatMapcrash.gzip); grammars become 427 on-demand chunks. Layout-independent (same result
under pnpm hoisted and isolated).
Test Plan
pnpm --filter web run buildsucceeds.shikichunk statically imports only the rolldownruntime (no cross-chunk cycle) and contains
bundledLanguagesAliasco-located with its reader — under both hoisted and isolated node_modules.
emitted separately and are NOT
modulepreloaded byindex.html.markdown code block and confirm syntax highlighting renders.
Demo
N/A
Type of change
Test coverage
Coverage notes
Verified via build output analysis: the
shikicore chunk is acyclic with thealias map co-located (cycle fix preserved), and language grammars are emitted as
separate, non-preloaded chunks. Existing Shiki/code-block tests exercise the
runtime highlighting path; this change only affects chunk grouping, not module
behavior.
Changelog
Faster initial load — syntax-highlighting language grammars now load on demand instead of all upfront.
Signed-off-by: Zeyi (Rice) Fan zeyi.f@databricks.com