tree shaking 通过静态分析移除未使用的 es 模块代码以减小体积、提升性能,需确保全量使用 import/export、显式声明 sideeffects、按需导入、避免顶层副作用,并借助工具验证效果。

Tree Shaking 通过静态分析移除未使用的 JavaScript 代码,直接减小打包体积、缩短加载时间、降低内存开销,是提升前端性能最有效的构建层手段之一。它不改变运行逻辑,却能让首屏渲染(FCP)更快、交互准备就绪(TTI)更早、Lighthouse 性能评分更高。
确保模块系统支持静态分析
Tree Shaking 只对 ES 模块(import/export)生效,CommonJS(require/module.exports)因动态特性无法被准确分析。
- 项目内所有自定义模块必须使用
import和export,禁止混用require - 引入第三方库时优先选 ESM 版本,例如用
lodash-es替代lodash,用date-fns替代moment - 若依赖库仅提供 CommonJS,可通过插件转换(如 Vite 的
vite-plugin-commonjs或 Webpack 的babel-plugin-transform-commonjs),但效果有限,建议优先替换为原生 ESM 库
显式声明副作用(sideEffects)
Webpack 默认保守处理——只要模块可能产生副作用(如注入样式、修改全局对象、执行 polyfill),就不会摇掉整个文件,哪怕只用了其中一小部分。
- 在
package.json中添加"sideEffects": false,表示项目中所有模块均无副作用,可安全摇树 - 如有真实副作用(如全局 CSS、字体加载、polyfill 脚本),明确列出路径:
"sideEffects": ["./src/polyfill.js", "./styles/index.css"] - 避免在模块顶层写有实际影响的语句,例如:
console.log('init')、document.body.classList.add('loaded'),这些都会被识别为副作用而阻止摇树
按需导入 + 避免全量引用
即使 Tree Shaking 开启,错误的导入方式仍会让整块代码“幸存”下来。
- 禁用全量导入:
import _ from 'lodash-es'→ 改为import debounce from 'lodash-es/debounce' - 组件库推荐使用 ESM 路径或配套插件,如 Ant Design +
babel-plugin-import,或直接用antd/es/button等子路径 - 自定义工具函数库建议拆分为独立导出文件(
utils/date.js、utils/string.js),而非单个大模块统一导出
验证与持续优化
配置完成不等于效果落地,必须检查最终产物是否真正精简。
- 使用
source-map-explorer或webpack-bundle-analyzer可视化分析 bundle 构成,定位未被摇掉的大模块 - 开启 Webpack 的
optimization.usedExports: true和TerserPlugin的compress.unused: true,强化死代码标记与删除 - 对高风险模块(含
eval、with、try/catch或动态表达式)保持警惕——它们会干扰静态分析,必要时抽离为独立 chunk 或手动标记/*#__PURE__*/
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











