Spit dependencies into chunks
This commit is contained in:
100
vite.config.js
100
vite.config.js
@@ -119,6 +119,14 @@ export default defineConfig({
|
||||
// which precaching would undo. They're served via the
|
||||
// `sticker-library` runtimeCaching rule below instead.
|
||||
globIgnores: ['**/stickers/**'],
|
||||
// Note: we deliberately do NOT raise `maximumFileSizeToCacheInBytes`
|
||||
// here. The default 2 MiB cap is a useful regression alarm — if
|
||||
// a future change pushes any chunk past it, the build fails loudly
|
||||
// and we know to either split further or investigate why a chunk
|
||||
// grew. Earlier this file overrode the cap to 5 MiB because the
|
||||
// pre-split bundle was 2.32 MB; that override was removed once
|
||||
// `build.rollupOptions.output.manualChunks` (below in this config)
|
||||
// brought every chunk under the default cap.
|
||||
runtimeCaching: [
|
||||
{
|
||||
urlPattern: /^https:\/\/cdn\.huggingface\.co\/.*/i,
|
||||
@@ -198,5 +206,95 @@ export default defineConfig({
|
||||
'/exports': { target: 'http://localhost:3001', changeOrigin: true },
|
||||
},
|
||||
},
|
||||
build: { outDir: 'dist' },
|
||||
build: {
|
||||
outDir: 'dist',
|
||||
// ────────────────────────────────────────────────────────────────
|
||||
// Manual chunk splitting
|
||||
// ────────────────────────────────────────────────────────────────
|
||||
//
|
||||
// Why we split rather than ship one bundle
|
||||
// ─────────────────────────────────────────
|
||||
// 1. Workbox precache cap. The PWA plugin's default
|
||||
// `maximumFileSizeToCacheInBytes` is 2 MiB. A single bundle
|
||||
// containing Konva + react-konva + @huggingface/transformers +
|
||||
// react + filerobot + everything else easily clears 2.3 MB,
|
||||
// which fails the precache step. Splitting keeps every chunk
|
||||
// comfortably under the cap without needing to override it.
|
||||
//
|
||||
// 2. Browser cache reuse across deploys. When app code changes
|
||||
// (the common case during active development), only the
|
||||
// `index` chunk's hash flips; vendor chunks (Konva, React,
|
||||
// transformers) keep their old hash and stay cached in users'
|
||||
// browsers. That means returning users only re-download the
|
||||
// relatively-small app chunk, not the 1-MB-each library
|
||||
// chunks that haven't changed.
|
||||
//
|
||||
// 3. Parallel download. Browsers can fetch multiple chunks
|
||||
// concurrently on HTTP/2, so loading 4 × 600 KB chunks is
|
||||
// typically faster than 1 × 2.3 MB chunk on broadband, even
|
||||
// before considering caching.
|
||||
//
|
||||
// What goes where
|
||||
// ───────────────
|
||||
// transformers/ @huggingface/transformers \u2014 the in-browser
|
||||
// ML runtime used for background removal.
|
||||
// Biggest single dependency. Only the
|
||||
// inference engine is bundled here; the
|
||||
// actual ML model weights stream from the
|
||||
// huggingface CDN at runtime (see
|
||||
// `transformers-models` / `transformers-lfs`
|
||||
// runtimeCaching rules above for offline
|
||||
// re-use).
|
||||
// konva/ konva + react-konva + use-image \u2014 the canvas
|
||||
// stack. All three are needed together
|
||||
// because react-konva wraps konva and
|
||||
// use-image wraps it for React consumption.
|
||||
// Grouping prevents one from being inlined
|
||||
// into a chunk that doesn't otherwise need
|
||||
// the others.
|
||||
// react-vendor/ react + react-dom \u2014 stable, every visitor
|
||||
// needs them, perfect for long-term caching.
|
||||
// filerobot/ react-filerobot-image-editor \u2014 mid-size,
|
||||
// used only when the user opens the advanced
|
||||
// image editor. Worth its own chunk so the
|
||||
// rest of the app doesn't pay for it.
|
||||
// index/ Everything else: app code, react-select,
|
||||
// styled-components, zod, uuid, plus all
|
||||
// the small utilities. This stays the
|
||||
// "main" chunk that changes with each deploy.
|
||||
//
|
||||
// What we deliberately did NOT split
|
||||
// ──────────────────────────────────
|
||||
// The smaller deps (react-select, styled-components, zod, uuid,
|
||||
// @emotion/is-prop-valid) stay in the index chunk on purpose.
|
||||
// Pulling them out would create chunks under 50 KB each, which
|
||||
// adds HTTP overhead (per-request connection cost, separate
|
||||
// hash entries in the precache manifest) without meaningfully
|
||||
// helping cache reuse. The "many small chunks" antipattern is
|
||||
// worse than a moderately-sized index chunk that includes the
|
||||
// long tail.
|
||||
//
|
||||
// If a future change makes one of these grow significantly (say,
|
||||
// a styled-components major upgrade that doubles its size), it
|
||||
// becomes worth pulling into its own chunk \u2014 but only then.
|
||||
//
|
||||
// Maintenance: when adding a new heavy dependency
|
||||
// ───────────────────────────────────────────────
|
||||
// 1. Build and check `dist/assets/` for which chunk it landed in.
|
||||
// 2. If it bloated the `index` chunk past comfort (rule of thumb:
|
||||
// if index alone is > 1 MiB), add a new entry to manualChunks
|
||||
// targeting that package name.
|
||||
// 3. The 2 MiB workbox cap acts as the loud alarm \u2014 if you forget,
|
||||
// the build fails and tells you exactly which chunk overflowed.
|
||||
rollupOptions: {
|
||||
output: {
|
||||
manualChunks: {
|
||||
'transformers': ['@huggingface/transformers'],
|
||||
'konva': ['konva', 'react-konva', 'use-image'],
|
||||
'react-vendor': ['react', 'react-dom'],
|
||||
'filerobot': ['react-filerobot-image-editor'],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user