Tree Shaking 的原理和使用方法

Tree Shaking 的原理和使用方法

December 20, 2024

是什么

Tree Shaking 是 JS 的一项重要优化技术,通过分析代码,删掉那些实际没有被使用的代码,减小生产构建的体积,从而提升应用的加载速度和性能。

原理

Tree Shaking 依赖于 ES6 Module 语法的静态特性,例如 importexport,通过静态分析来确定哪些模块和变量没有被使用,通常通过抽象语法树(AST)来实现。

Tree Shaking 的概念最早由 Rollup 普及,现在已经成为 JS 优化的共识。对于打包工具(Webpack、Rollup等),在编译阶段,构建工具(Webpack、Rollup 等)会分析并标记未被引用的模块和变量,在最终打包时将其剔除。Vue3 也引入了模块化设计,允许按需导入,从而实现更好的 Tree Shaking。

构建工具配置 Tree Shaking

Webpack、Vite 和 Rollup 都支持 Tree Shaking,下面简单讲下如何配置以及注意事项。

Webpack

  1. 确保使用 ES6 模块语法,例如:
export function add(a, b) {
  return a + b
}
export function subtract(a, b) {
  return a - b
}
  1. 配置 package.json

package.json 中配置 sideEffects,告诉 Webpack 哪些文件有副作用,哪些文件可以安全的进行 Tree Shaking。

什么是 sideEffects?

sideEffects副作用,指模块在被导入时,除了导出模块,还会执行一些额外的操作,例如:

  • 修改全局变量
  • 动态加载资源(如CSS文件)
  • 执行一些初始化逻辑

如果没有副作用文件,直接设置为 false:

{
  "sideEffects": false
}

如果有副作用文件,可指定文件路径:

{
  "sideEffects": [
    "*.css",
    "src/some-module.js"
  ]
}
  1. 启用生产模式

在生产模式下,Webpack 会自动进行 Tree Shaking 和代码压缩

module.exports = {
  mode: "production",  // 开启生产模式
  optimization: {
    useExports: true  // 开启 Tree Shaking
  }
}

Warning

如果使用了 Babel,要确保它不会将 ES6 Module 转换为 CommonJS Module,在 babelrcbabel.config.js 中配置:

{
  "presets": [
    ["@babel/preset-env", { "modules": false }] // 保留 ES6 模块语法
  ]
}

Vite 和 Rollup

Vite 和 Rollup 默认启用 Tree Shaking,确保使用 ES6 Module 语法,并在 package.json 文件中设置 sideEffects: false,打包即可。

CSS Tree Shaking

除了 JS 外,通过 purifyCSS plugin,CSS 也可以实现 Tree Shaking。

https://cloud.tencent.com/developer/article/1617110