The page from Custom Builds with Sass uses a navbar, the grid, buttons, cards, a modal and a dozen utilities, yet it ships 239 kB of CSS and 81 kB of JavaScript. Three independent steps shrink it.
Lean Sass 22,539 imports. Replace step 5 of styles.scss with the partials you use; the build fails loudly if a partial needs one you left out.
@import "bootstrap/scss/maps", "bootstrap/scss/mixins", "bootstrap/scss/utilities",
"bootstrap/scss/root", "bootstrap/scss/reboot", "bootstrap/scss/type",
"bootstrap/scss/containers", "bootstrap/scss/grid", "bootstrap/scss/buttons",
"bootstrap/scss/transitions", "bootstrap/scss/navbar", "bootstrap/scss/card",
"bootstrap/scss/modal", "bootstrap/scss/utilities/api";Per-plugin JavaScript. Each Bootstrap 5.3 2,007 plugin registers its data API as soon as its module runs, so bundlers cannot drop unused plugins: import { Modal } from 'bootstrap' still produced the full 81 kB here. A deep import, import Modal from 'bootstrap/js/dist/modal', brings in only the modal and its helpers.
PurgeCSS 955,901 . PurgeCSS (https://github.com/FullHuman/purgecss 8,051 ) (MIT) extracts every word that could be a class, id or tag from your content files and deletes CSS rules whose selectors match none of them. Install @fullhuman/postcss-purgecss and run it in Vite 25,978 's PostCSS 238,379 step for production builds only:
import { defineConfig } from 'vite';
import purgeCSSPlugin from '@fullhuman/postcss-purgecss';
export default defineConfig(({ mode }) => ({
css: {
preprocessorOptions: {
scss: { silenceDeprecations: ['import', 'global-builtin', 'color-functions', 'if-function'] },
},
postcss: {
plugins: mode === 'production' ? [purgeCSSPlugin({
// markup, your scripts, and the Bootstrap plugins you import
content: ['index.html', 'src/**/*.js', 'node_modules/bootstrap/js/dist/{modal,util/*}.js'],
})] : [],
},
},
}));| Build of the same page | CSS (gzip) | JS (gzip) |
|---|---|---|
| CDN files | 232.1 kB (30.8) | 80.5 kB (23.7) |
| Sass overrides, full import | 239.0 kB (31.8) | 81.0 kB (24.2) |
| + deep modal import | 239.0 kB (31.8) | 23.2 kB (7.5) |
| + lean Sass imports | 132.3 kB (18.4) | 23.2 kB (7.5) |
| + PurgeCSS | 19.1 kB (4.8) | 23.2 kB (7.5) |
PurgeCSS alone, on the full import, reached 20.3 kB, but lean imports also cut the build from 3.0 s to 2.1 s and can never delete a class by mistake. PurgeCSS can. The modal creates <div class="modal-backdrop"> at run time, a name found only in util/backdrop.js; without that glob the modal opens over an undimmed page. Class names built in code (` btn-${variant} ) or arriving from a CMS need the safelist option (safelist: [/^btn-/]`).