Skip to content

Tree Shaking

Tree-shaking (摇树优化)是一种通过静态分析消除 JavaScript 代码中未使用部分的技术,旨在减少最终构建产物体积,提升加载速度和运行效率。其名称源自“摇晃树干使枯叶掉落”的比喻,核心思想是去除未被引用的“死代码”(Dead Code)。

Tree-shaking 的作用

  1. 减少打包体积

    • 通过删除未使用的模块、函数或变量(如第三方库中未被调用的方法),显著缩小代码体积;
  2. 优化性能

    • 减少网络传输时间和内存占用,提升页面加载速度,尤其对移动端和低带宽环境效果明显;
  3. 支持按需加载

    • 结合模块化开发,实现按需引入功能(如仅导入组件库中的特定组件);
  4. 生产环境优化

    • 在 Webpack 生产模式(mode: 'production')下默认启用,结合代码压缩工具(如 Terser)进一步优化。

Tree-shaking 的工作原理

  1. 静态分析依赖关系

    • 基于 ES Module:ES6 模块的导入(import)和导出(export)是静态的,依赖关系在编译时即可确定,支持可靠的分析。
    • 构建依赖树:从入口文件出发,解析所有模块的依赖关系,形成抽象语法树(AST)
  2. 标记未使用代码

    • 通过工具(如 Webpack)标记未被引用的导出项(如函数、变量),如添加 /* unused harmony export */ 注释。
  3. 删除死代码

    • 结合压缩工具(如 TerserUglifyJS)将标记的代码从最终产物中移除。
js
// 示例 utils.js
export function a() { } // 被标记为未使用
export function b() { } // 被使用
// 打包后仅保留 function b() {}

Tree-shaking 的注意事项

  1. 必须使用 ES Module 语法

    • CommonJS(如 require / module.exports )因动态依赖特性无法被静态分析,Tree-shaking 仅对 ES Module 有效。
  2. 避免副作用代码(Side Effects)

    • 副作用代码(如修改全局变量、执行立即函数)可能被误删,需通过 package.json"sideEffects" 字段标注:
      • false:所有文件无副作用,可安全删除未使用代码。
      • ["*.css"]:指定含副作用的文件(如 CSS 导入)。
  3. 配置 Babel 避免破坏 ES Module

    • Babel 默认将 ES Module 转换为 CommonJS,需设置 preset-envmodules: false 保留原始语法。
  4. 生产环境优化

    • Webpack 需配置 mode: 'production' 以启用压缩和 Tree-shaking。
  5. 第三方库的兼容性

    • 确保第三方库使用 ES Module 导出(如 Lodash 的 ESM 版本 lodash-es)。

Tree-shaking 的局限性

  1. 动态导入无法分析

    • import() 动态加载的模块需结合代码分割(Code Splitting)优化。
  2. 默认导出对象难以优化

js
// 无法判断对象中哪些属性被使用
export default { a : 1 , b : 2 };
  1. 无法处理运行时依赖

    • 如通过字符串拼接生成的模块路径(如 require('module/' + path) )。

如有转载或 CV 的请标注本站原文地址