Tree-Shaking 作用和实现原理

这篇具有很好参考价值的文章主要介绍了Tree-Shaking 作用和实现原理。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、什么是Tree-shaking

Tree-shaking 它的名字来源于通过摇晃(shake)JavaScript代码的抽象语法树(AST),是一种用于优化JavaScript代码的技术,主要用于移除未被使用的代码,使得最终生成的代码包含应用程序中实际使用的部分。这主要用于减小应用程序的体积,提高加载性能。

在前端开发中,特别是在使用模块化工具(如Webpack、Rollup等)构建应用程序时,通常会引入许多库和模块。然而,应用程序可能只使用了这些库的一小部分功能,导致最终生成的代码包含了大量未被使用的代码。Tree-shaking通过静态分析代码来确定哪些代码是可到达的并且被使用的,然后去除那些未被使用的部分。这样一来,可以显著减小最终部署的代码大小,提高应用程序的性能。

Tree Shaking 较早前由 Rich Harris 在 Rollup 中率先实现,Webpack 自 2.0 版本开始接入,已经成为一种应用广泛的性能优化手段。

Tree-Shaking 作用和实现原理,tree-shaking

上图形象的解释了Tree-shaking 的本意,本文所说的前端中的tree-shaking可以理解为通过具"摇"我们的JS文件,实际开发中,虽然依赖了某个模块,但其实只使用其中的某些功能。通过 tree-shaking,将没有使用的模块摇掉,这样来达到删除无用代码的目的。

在 Webpack 中,启动 Tree Shaking 功能必须同时满足三个条件:

  • 使用 ESM 规范编写模块代码
  • 配置 optimization.usedExportstrue,启动标记功能
  • 启动代码优化功能,可以通过如下方式实现:
    • 配置 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 = 'foo'

export {
   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 的引入方式。

  • ESM:export + import
  • Common JS:module.exports + require
// 导入所有内容(不会触发 tree-shaking)
import lodash from 'lodash'
 
// 导入命名导出 (会触发 tree-shaking)
import { debounce } from 'lodash'

注意:如果想要做到 tree shaking,那么在引入模块时就应该避免全部引入。应该采用按需引入,才可以触发 tree shaking 机制。

二、实现原理

Tree Shaking在去除代码冗余的过程中,程序会从入口文件出发扫描所有的模块依赖,以及模块的子依赖,然后将它们链接起来形成一个“抽象语法树”(AST)。随后,运行所有代码,查看哪些代码是用到过的,做好标记。最后,再将“抽象语法树”中没有用到的代码“摇落”。经历这样一个过程后,就去除了没有用到的代码。

Tree-Shaking 作用和实现原理,tree-shaking

Webpack 中,Tree-shaking 的实现一是先「标记」出模块导出值中哪些没有被用过,二是使用 Terser 删掉这些没被用到的导出语句。标记过程大致可划分为三个步骤:

  • Make 阶段,收集模块导出变量并记录到模块依赖关系图 ModuleGraph 变量中
  • Seal 阶段,遍历 ModuleGraph 标记模块导出变量有没有被使用
  • 生成产物时,若变量没有被其它模块使用则删除对应的导出语句

标记功能需要配置 optimization.usedExports = true 开启

在ES Module中,我们可以将模块的加载分为两个阶段:静态分析和编译执行;

所谓静态分析,即在代码执行前就能对整体代码依赖调用关系等进行分析读取;

下面我们看下ES Module的特性:

  1. 只能作为模块顶层的语句出现(而不嵌套在条件语句中)
  2. import 的模块名只能是字符串常量(只对文件进行字符串读取)
  3. 导入和导出语句没有动态部分(不允许使用变量等)

三、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 为 'production',Webpack 默认启用 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文章来源地址https://www.toymoban.com/news/detail-820105.html

    ESBuild 是一个极快的 JavaScript 构建工具,它具有强大的 Tree-shaking 功能。ESBuild 以速度为特点,能够在短时间内完成快速的构建。

到了这里,关于Tree-Shaking 作用和实现原理的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 高级数据结构与算法 | 布谷鸟过滤器(Cuckoo Filter):原理、实现、LSM Tree 优化

    如果对布隆过滤器不太了解,可以看看往期博客:海量数据处理(一) :位图与布隆过滤器的概念以及实现 布隆过滤器 局限 对于需要处理海量数据的时候,如果我们需要快速判断一条记录是否,通常会使用过滤器来进行验证,而其中最常见的就是布隆过滤器(Bloom Filter)—

    2024年02月19日
    浏览(49)
  • 决策树(Decision Tree)原理解析:从基本概念到建立模型

    决策树是一种常用的机器学习算法,用于解决分类和回归问题。它基于树形结构进行决策,通过一系列的分裂和判断条件来预测目标变量的值。本文将详细解析决策树的原理,从基本概念到建立模型的过程 决策树由节点和边组成,其中节点表示特征或属性,边表示特征的取值

    2024年02月10日
    浏览(45)
  • el-tree 实现节点高亮

    要实现显示  el-tree  节点高亮,可以使用  el-tree  提供的  highlight-current  属性和  current-node-key  属性,以及  el-tree-node  组件提供的  highlight  属性。 首先,在  el-tree  组件中设置  highlight-current  属性为  true ,表示启用高亮当前节点的功能: 然后,在  el-tree  组件中

    2024年02月08日
    浏览(48)
  • element UI tree 搜索功能实现

    最近需求想要一个树状结构的带搜索功能的目录,要求目录包含搜索文字的高亮,如果父级收起则父级高亮,如果跨级收起 则收起的级别高亮 不限制层级 例如:搜索文字为D,收起C则C高亮, 直接收起A则A高亮 A           B                 C              

    2024年04月29日
    浏览(35)
  • elementUI Tree 树形控件单选实现

    在Element UI中,树形控件(el-tree)本身不支持单选功能。但是,你可以通过监听节点点击事件并手动更新选中状态来实现单选树。 以下是一个简单的例子,展示了如何实现单选功能: html相关: js方法: 义了一个currentNodeKey来存储当前选中节点的 key。每次点击节点时,我们首

    2024年03月25日
    浏览(53)
  • naive UI tree组件实现增删改功能

    目录 1.tree组件  2.实现思路 3.代码实现 1. 页面部分 2.js部分: 1.节点内容渲染函数 2.节点后缀渲染函数 3.节点点击事件      naive UI是Vue 3是组件库,其中的tree组件可以生成树形目录结构,官网提供了很多功能演示,例如拖放节点等。但是并没有提供增删改功能的演示。    

    2024年02月12日
    浏览(46)
  • Solidity实现默克尔树 Merkle Tree

    ​ ​Merkle Tree​ ​​,也叫默克尔树或哈希树,是区块链的底层加密技术,被BTC和Ethereum区块链广泛采用。​ ​Merkle Tree​ ​​是一种自下而上构建的加密树,每个叶子是对应数据的哈希,而每个非叶子为它的​ ​2​ ​个子节点的哈希。 ​ ​Merkle Tree​ ​允许对大型数据

    2024年01月16日
    浏览(35)
  • 【前端】- 在使用Element UI 的el-tree组件时,从底层去研究如何去实现一键展开/关闭【tree节点】的功能

    点击前效果: 点击后效果: 页面部分:这里是简单的数结构渲染,不多讲,$refs.Reftree获取的是el-tree的实例,具体作用请看下面的方法。 方法部分:该方法传入el-tree实例,直接点击按钮即可实现展开或者关闭,这里简单讲解一下 1、ref.store.root.childNodes 通过实例来调用tree组

    2024年04月16日
    浏览(58)
  • element ui tree树形控件实现单选操作

    template     div class=\\\"createPost-container\\\"         el-form ref=\\\"postForm\\\" :model=\\\"postForm\\\" class=\\\"form-container\\\"             div class=\\\"createPost-main-container\\\"                 el-row                     el-col :span=\\\"24\\\"                         el-form-itemspan style=\\\"color:red;\\\"提示:带

    2024年02月06日
    浏览(48)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包