按需编译 Sass 是真正减体积的核心:删全量 CSS/JS 引用,改用官方 Sass 源码按需导入 grid、buttons 等模块,并显式引入 JS 组件(如 import { Modal } from 'bootstrap/js/index.esm.js'),禁用自动初始化,最终通过 Network 面板和 Lighthouse 验证实际体积与未用 CSS。

直接用 bootstrap.min.css 和 bootstrap.bundle.min.js 是最基础的压缩手段,但只做这一步,移动端流量几乎没省多少——真正吃带宽的是你根本没用的那 80% 组件代码。
为什么换 .min 文件效果有限
压缩版只是删空格注释,不删功能。v5.3.3 的 bootstrap.min.css 未 gzip 前仍约 70KB,gzip 后约 22KB;bootstrap.bundle.min.js gzip 后约 35KB。加起来近 60KB,看似不大,但这是「全量组件」的体积。如果你页面只用 container、btn、row/col,那其中至少 50KB 是冗余传输。
- 浏览器必须下载并解析全部 CSS 才能绘制首屏,哪怕你只用了 3 个类
- JS 里
Modal、Tooltip、Carousel的构造函数全在内存里占着,哪怕你一个都没调用 - CDN 上没加
integrity属性时,浏览器无法复用跨站缓存,反而多一次请求校验
按需编译 Sass 才是真正减体积的核心
删掉所有对 bootstrap/dist/css/bootstrap.min.css 的引用,改走官方 Sass 源码路径。这是目前最可控、无副作用、且构建产物可预测的裁剪方式。
- 新建
src/custom-bootstrap.scss,严格按顺序导入:@import "bootstrap/scss/functions"→@import "bootstrap/scss/variables"→@import "bootstrap/scss/mixins" - 只加你真实用到的模块,比如:
@import "bootstrap/scss/grid"、@import "bootstrap/scss/buttons"、@import "bootstrap/scss/utilities" - 确认注释掉所有不用的模块:
@import "bootstrap/scss/modal"、@import "bootstrap/scss/popover"、@import "bootstrap/scss/images" - 如果 utility 类只用
mt-2、d-none这类基础项,就重写$utilities变量,禁用shadow、border等整组规则
JS 必须显式导入,禁用自动初始化
全量引入 bootstrap.bundle.min.js 会让 Popper、Modal、Dropdown 全打进首屏 JS,且 Webpack/Rollup 默认无法 tree-shake 掉——因为它的主入口导出仍是对象形式,不是纯 ESM 静态 import/export。
立即学习“前端免费学习笔记(深入)”;
- 改用 ES 模块入口:
import { Modal, Toast } from 'bootstrap/js/index.esm.js'(注意路径,不是dist/js/...) - 确保项目
package.json中声明"sideEffects": false,否则构建工具不敢剔除“看似没用”的模块 - 避免使用
data-bs-toggle自动初始化,改用手动调用:new Modal(document.getElementById('my-modal')),这样连事件监听器都只在需要时绑定 - 移动端点击延迟问题(300ms)不是 Bootstrap 的 bug,而是未禁用
touchstart监听所致;手动初始化后可配合fastclick或原生touch-action: manipulation解决
最终体积是否真降下来,别只信构建日志——打开 DevTools 的 Network 面板,过滤 .css 和 .js,看实际加载的字节数;再用 Lighthouse 跑一次移动端模拟,重点关注 FCP 和 unused CSS 字节数。很多团队卡在“以为做了优化”,其实 @import "bootstrap/scss/bootstrap" 还藏在某个 SCSS 文件里没删干净,或者图标字体 bootstrap-icons.css 仍通过 CDN 全量加载,这些细节才是移动端流量居高不下的真正原因。


















