feat: code splitting optimization - reduce initial bundle by 36% (#8542)

## Summary

Reduces initial module preload from 12.94 MB to 8.24 MB (-4.7 MB, -36%).

## Changes

- Split vendor chunks for better cache isolation (firebase, sentry,
i18n, zod, etc.)
- Exclude heavy optional chunks from initial preload: THREE.js, xterm,
tiptap, chart.js, yjs
- Lazy load 16 dialog components in dialogService
- Add \endor-yjs\ chunk for CRDT library

## Metrics

| Metric | Before | After |
|--------|--------|-------|
| Initial preload | 12.94 MB | 8.24 MB |
| vendor-other | 4,006 KB | 2,156 KB |
| dialogService | 1,860 KB | 1,304 KB |

All excluded chunks still load on-demand when their features are used.

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-8542-feat-code-splitting-optimization-reduce-initial-bundle-by-36-2fb6d73d36508146aaf7fdaed3274033)
by [Unito](https://www.unito.io)

---------

Co-authored-by: Amp <amp@ampcode.com>
Co-authored-by: github-actions <github-actions@github.com>
This commit is contained in:
Alexander Brown
2026-02-02 19:05:28 -08:00
committed by GitHub
parent 21492ecca5
commit cbdc7d030f
17 changed files with 423 additions and 100 deletions

View File

@@ -419,6 +419,31 @@ export default defineConfig({
minify: SHOULD_MINIFY,
target: 'es2022',
sourcemap: GENERATE_SOURCEMAP,
// Exclude heavy optional vendor chunks from initial module preload
// These chunks are only needed when their features are used (3D, terminal, etc.)
modulePreload: {
resolveDependencies: (_filename, deps, { hostType }) => {
// Only filter for HTML entry points, not for dynamic imports
if (hostType !== 'html') return deps
// Exclude heavy vendor chunks that should be lazy-loaded
// - vendor-three: 3D preview (Load3D nodes)
// - vendor-xterm: Terminal emulator (logs panel)
// - vendor-tiptap: Rich text editor (markdown widgets)
// - vendor-chart: Chart.js (stats/monitoring)
// - vendor-yjs: CRDT library (layout store, loaded on first graph)
const lazyVendors = [
'vendor-three',
'vendor-xterm',
'vendor-tiptap',
'vendor-chart',
'vendor-yjs'
]
return deps.filter(
(dep) => !lazyVendors.some((vendor) => dep.includes(vendor))
)
}
},
rolldownOptions: {
treeshake: {
manualPureFunctions: [
@@ -442,52 +467,100 @@ export default defineConfig({
'console.trace'
]
},
experimental: {
strictExecutionOrder: true
},
output: {
keepNames: true,
codeSplitting: {
groups: [
// Framework core - highest priority, very stable
{
name: 'vendor-vue-core',
test: /[\\/]node_modules[\\/](vue|@vue|pinia|vue-router)[\\/]/,
priority: 20
},
{
name: 'vendor-firebase',
test: /[\\/]node_modules[\\/](@?firebase|@firebase)[\\/]/,
priority: 15
},
{
name: 'vendor-sentry',
test: /[\\/]node_modules[\\/]@sentry[\\/]/,
priority: 15
},
// UI component libraries
{
name: 'vendor-primevue',
test: /[\\/]node_modules[\\/](@?primevue|@primeuix)[\\/]/,
priority: 10
},
{
name: 'vendor-tiptap',
test: /[\\/]node_modules[\\/]@tiptap[\\/]/,
priority: 10
},
{
name: 'vendor-chart',
test: /[\\/]node_modules[\\/]chart\.js[\\/]/,
priority: 10
},
{
name: 'vendor-three',
test: /[\\/]node_modules[\\/](three|@sparkjsdev)[\\/]/,
priority: 10
},
{
name: 'vendor-xterm',
test: /[\\/]node_modules[\\/]@xterm[\\/]/,
priority: 10
},
{
name: 'vendor-vue',
test: /[\\/]node_modules[\\/](vue|pinia)[\\/]/,
priority: 10
priority: 15
},
{
name: 'vendor-reka-ui',
test: /[\\/]node_modules[\\/]reka-ui[\\/]/,
priority: 10
priority: 15
},
// Heavy optional features
{
name: 'vendor-three',
test: /[\\/]node_modules[\\/](three|@sparkjsdev)[\\/]/,
priority: 15
},
{
name: 'vendor-tiptap',
test: /[\\/]node_modules[\\/]@tiptap[\\/]/,
priority: 15
},
{
name: 'vendor-chart',
test: /[\\/]node_modules[\\/]chart\.js[\\/]/,
priority: 15
},
{
name: 'vendor-xterm',
test: /[\\/]node_modules[\\/]@xterm[\\/]/,
priority: 15
},
{
name: 'vendor-yjs',
test: /[\\/]node_modules[\\/](yjs|lib0)[\\/]/,
priority: 15
},
// Utilities and validation
{
name: 'vendor-vueuse',
test: /[\\/]node_modules[\\/]@vueuse[\\/]/,
priority: 12
},
{
name: 'vendor-i18n',
test: /[\\/]node_modules[\\/](vue-i18n|@intlify)[\\/]/,
priority: 12
},
{
name: 'vendor-zod',
test: /[\\/]node_modules[\\/](zod|zod-validation-error)[\\/]/,
priority: 12
},
{
name: 'vendor-axios',
test: /[\\/]node_modules[\\/]axios[\\/]/,
priority: 12
},
{
name: 'vendor-markdown',
test: /[\\/]node_modules[\\/](marked|dompurify)[\\/]/,
priority: 12
},
// Catch-all for remaining node_modules
{
name: 'vendor-other',
test: /[\\/]node_modules[\\/]/,
priority: 0
priority: 0,
minSize: 10000
}
]
}