河北建设厅身份认证锁登录网站,网站logo优化,行业型网站 赢利点,程序开发合同一、什么是Tree-shaking
Tree-shaking 它的名字来源于通过摇晃#xff08;shake#xff09;JavaScript代码的抽象语法树#xff08;AST#xff09;#xff0c;是一种用于优化JavaScript代码的技术#xff0c;主要用于移除未被使用的代码#xff0c;使得最终生成的代码包…一、什么是Tree-shaking
Tree-shaking 它的名字来源于通过摇晃shakeJavaScript代码的抽象语法树AST是一种用于优化JavaScript代码的技术主要用于移除未被使用的代码使得最终生成的代码包含应用程序中实际使用的部分。这主要用于减小应用程序的体积提高加载性能。
在前端开发中特别是在使用模块化工具如Webpack、Rollup等构建应用程序时通常会引入许多库和模块。然而应用程序可能只使用了这些库的一小部分功能导致最终生成的代码包含了大量未被使用的代码。Tree-shaking通过静态分析代码来确定哪些代码是可到达的并且被使用的然后去除那些未被使用的部分。这样一来可以显著减小最终部署的代码大小提高应用程序的性能。
Tree Shaking 较早前由 Rich Harris 在 Rollup 中率先实现Webpack 自 2.0 版本开始接入已经成为一种应用广泛的性能优化手段。 上图形象的解释了Tree-shaking 的本意本文所说的前端中的tree-shaking可以理解为通过具摇我们的JS文件实际开发中虽然依赖了某个模块但其实只使用其中的某些功能。通过 tree-shaking将没有使用的模块摇掉这样来达到删除无用代码的目的。
在 Webpack 中启动 Tree Shaking 功能必须同时满足三个条件
使用 ESM 规范编写模块代码配置 optimization.usedExports 为 true启动标记功能启动代码优化功能可以通过如下方式实现 配置 mode production配置 optimization.minimize true提供 optimization.minimizer 数组
// webpack.config.js
module.exports {entry: ./src/index,mode: production,devtool: false,optimization: {usedExports: true // 启用tree-shaking}
}示例代码
// bar.js
const bar bar
const foo fooexport {bar,foo
}// index.js
import { bar } from ./bar // 引入bar.js
console.log(bar)
示例中bar.js 模块导出了 bar 、foo 但只有 bar 导出值被其它模块使用经过 Tree Shaking 处理后foo 变量会被视作无用代码删除。
Tree Shaking 只支持 ESM (ES6 Module)的引入方式不支持 Common JS 的引入方式。
ESMexport importCommon JSmodule.exports require
// 导入所有内容不会触发 tree-shaking
import lodash from lodash// 导入命名导出 (会触发 tree-shaking)
import { debounce } from lodash
注意如果想要做到 tree shaking那么在引入模块时就应该避免全部引入。应该采用按需引入才可以触发 tree shaking 机制。
二、实现原理
Tree Shaking在去除代码冗余的过程中程序会从入口文件出发扫描所有的模块依赖以及模块的子依赖然后将它们链接起来形成一个“抽象语法树”(AST)。随后运行所有代码查看哪些代码是用到过的做好标记。最后再将“抽象语法树”中没有用到的代码“摇落”。经历这样一个过程后就去除了没有用到的代码。 Webpack 中Tree-shaking 的实现一是先「标记」出模块导出值中哪些没有被用过二是使用 Terser 删掉这些没被用到的导出语句。标记过程大致可划分为三个步骤
Make 阶段收集模块导出变量并记录到模块依赖关系图 ModuleGraph 变量中Seal 阶段遍历 ModuleGraph 标记模块导出变量有没有被使用生成产物时若变量没有被其它模块使用则删除对应的导出语句 标记功能需要配置 optimization.usedExports true 开启 在ES Module中我们可以将模块的加载分为两个阶段静态分析和编译执行
所谓静态分析即在代码执行前就能对整体代码依赖调用关系等进行分析读取
下面我们看下ES Module的特性
只能作为模块顶层的语句出现而不嵌套在条件语句中import 的模块名只能是字符串常量只对文件进行字符串读取导入和导出语句没有动态部分不允许使用变量等 三、sideEffects 副作用
webpack 2 正式版本内置支持 ES2015 模块也叫做 harmony modules和未使用模块检测能力。新的 webpack 4 正式版本扩展了此检测能力通过 package.json 的 sideEffects 属性作为标记向 compiler 提供提示表明项目中的哪些文件是 pure(纯正 ES2015 模块)由此可以安全地删除文件中未使用的部分。
Webpack 中有一个 sideEffects 配置用于标识哪些模块是无副作用的可以被 Tree-shaking 移除。如果你的模块包含副作用但你明确知道这些副作用是无害的可以通过配置 sideEffects 来告诉 Webpack 哪些模块可以被 Tree-shaking 移除。
// package.json
{sideEffects: [*.css, *.scss]
}
四、哪些框架可以使用Tree-shaking Webpack Webpack 是一个强大的 JavaScript 模块打包工具支持 Tree-shaking。在 Webpack 2 及以上版本中配置 mode 为 productionWebpack 默认启用 Tree-shaking。同时确保你的项目使用了 ES6 模块系统以便 Webpack 能够更好地进行静态分析。 Rollup Rollup 是专注于 ES6 模块的打包工具天生支持 Tree-shaking。Rollup 的设计目标之一就是生成更小、更高效的代码因此它是一个非常适合 Tree-shaking 的选择。 Parcel Parcel 是一个零配置的打包工具它通过自动检测和处理模块间的依赖关系实现了快速且有效的 Tree-shaking。Parcel 可以用于快速搭建项目而无需复杂的配置。 Snowpack Snowpack 是一个现代的构建工具专注于提供快速的开发体验。它支持 ES6 模块和 Tree-shaking并在开发环境中实现了即时开发Instant Development的特性。 Vite Vite 是一个基于 Vue.js 的新型构建工具它利用原生 ES 模块导入的特性支持 Tree-shaking并在开发环境中实现了快速的冷启动。 ESBuild ESBuild 是一个极快的 JavaScript 构建工具它具有强大的 Tree-shaking 功能。ESBuild 以速度为特点能够在短时间内完成快速的构建。