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可以理解为通过具"摇"我们的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)。随后,运行所有代码,查看哪些代码是用到过的,做好标记。最后,再将“抽象语法树”中没有用到的代码“摇落”。经历这样一个过程后,就去除了没有用到的代码。

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/649975.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

大模型应用开发:为产品创建一个AI客服/智能助手

欢迎阅读本系列文章!我将带你一起探索如何使用OpenAI API来开发GPT大模型应用。无论你是编程新手还是资深开发者,都能在这里获得灵感和收获。 本文将继续展示AI助手的开发方式,在OpenAPI中它的名字是Assistants。 什么是Assistants&#xf…

Python网络爬虫实战——实验4:Python爬虫代理的使用

【实验内容】 本实验主要介绍在爬虫采集数据的过程中代理的使用。 【实验目的】 1、掌握代理使用的基本场景; 2、解决IP封锁问题; 3、提高爬虫访问效率; 【实验步骤】 步骤1选择代理服务提供商 步骤2配置爬虫使用代理 步骤3 采集数据生成…

priority_queue模拟

文章目录 模拟priority_queue性质:成员函数:向上调整、向下调整push/pop/empty/top/size/empty成员变量 仿函数struct和class练习题堆的一些性质 模拟priority_queue 性质: 是容器适配器; 底层逻辑是堆,适配器是vect…

【遥感专题系列】影像信息提取之——基于专家知识的决策树分类

可以将多源数据用于影像分类当中,这就是专家知识的决策树分类器,本专题以ENVI中Decision Tree为例来叙述这一分类器。 本专题包括以下内容: 专家知识分类器概述知识(规则)定义ENVI中Decision Tree的使用 概述 基于知…

数据结构与算法——队列

概述 计算机科学中,queue 是以顺序的方式维护的一组数据集合,在一端添加数据,从另一端移除数据。添加的一端称为尾,移除的一端称为头。 功能 插入offer(value : E) : boolean  取值并移除poll() : E  取值peek() : E  判断…

LeetCode 40.组合总和 II

组合总和 II 给定一个候选人编号的集合 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。 candidates 中的每个数字在每个组合中只能使用 一次 。 注意:解集不能包含重复的组合。 方法一、回溯 由于题目要求解集…

实体识别与分类方法综述

目录 前言1 实体识别简介2 基于模板和规则的方法3 基于序列标注的方法3.1 常见序列标注模型3.2 模型参数估计和学习问题3.3 常见序列预测模型 4. 基于深度学习的实体识别方法5 基于预训练语言模型的实体识别5.1 BERT、GPT等预训练语言模型5.2 解码策略 6 特殊问题与挑战6.1 标签…

如何提高记忆力?

许多学员经常问我:为什么您的记忆力那么好?有没有什么方法,可以提高记忆力? 今天,我想好好聊聊这个问题。 当然,学习和记忆,是一个巨大的话题。这篇文章只是一个初探。希望能帮你打开一些视野&a…

深入理解Redis:如何设置缓存数据的过期时间及其背后的机制

目录 Redis 给缓存数据设置过期时间 Redis是如何判断数据是否过期的呢? 过期的数据的删除策略 Redis 内存淘汰机制 Redis 给缓存数据设置过期时间 一般情况下,我们设置保存的缓存数据的时候都会设置一个过期时间。为什么呢? 因为内存是有…

电流检测电路设计方案汇总

电流检测电路设计方案(一) 低端检流电路的检流电阻串联到地(图1),而高端检流电路的检流电阻是串联到高电压端(图2)。两种方法各有特点:低端检流方式在地线回路中增加了额外的线绕电…

​ElasticSearch

目录 简介 基本概念 倒排索引 FST 简介 ES是一个基于lucene构建的,分布式的,RESTful的开源全文搜索引擎。支持对各种类型的数据的索引;搜索速度快,可以提供实时的搜索服务;便于水平扩展,每秒可以处理 …

响应式Web开发项目教程(HTML5+CSS3+Bootstrap)第2版 例5-1事件处理

代码 <!doctype html> <html> <head> <meta charset"utf-8"> <title>事件处理</title> </head><body> <input id"btn" type"button" name"btn" value"提交" /> <…

深入理解ZooKeeper分布式锁

第1章&#xff1a;引言 分布式系统&#xff0c;简单来说&#xff0c;就是由多台计算机通过网络相连&#xff0c;共同完成任务的系统。想象一下&#xff0c;咱们平时上网浏览网页、看视频&#xff0c;背后其实都是一大堆服务器在协同工作。这些服务器之间需要协调一致&#xff…

小游戏选型(二):第三方社交小游戏厂家对比,即构/声网/融云/云信等

前言&#xff1a; 上一篇文章我们主要介绍社交游戏化趋势&#xff0c;并分析了直播平台面临的买量贵、变现难等问题&#xff0c;探讨了小游戏作为新的运营变现玩法的优势。同时还列举了各大直播平台TOP5的小游戏。今天我们继续介绍小游戏系列内容&#xff0c;本文是该系列的第…

浪花 - 添加队伍业务开发

一、接口设计 1. 请求参数&#xff1a;封装添加队伍参数 TeamAddRequest package com.example.usercenter.model.request;import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.ann…

勤学苦练“prompts“,如沐春风“CodeArts Snap“

前言 CodeArts Snap 上手一段时间了&#xff0c;对编程很有帮助。但是&#xff0c;感觉代码编写的不尽人意。 我因此也感到困惑&#xff0c;想要一份完整的 CodeArts Snap 手册看看。 就在我感觉仿佛"独自彷徨在这条悠长、悠长又寂寥的雨巷"时&#xff0c;我听了大…

【数据库】聊聊explain如何优化sql以及索引最佳实践

在实际的开发中&#xff0c;我们难免会遇到一些SQL优化的场景&#xff0c;虽然之前也看过周阳的课程&#xff0c;但是一直没有进行细心的整理&#xff0c;所以本篇会进行详细列举explain的相关使用&#xff0c;以及常见的索引最佳实践&#xff0c;并通过案例进行讲解。 数据准…

Java复习系列之阶段三:框架原理

1. Spring 1.1 核心功能 1. IOC容器 IOC&#xff0c;全称为控制反转&#xff08;Inversion of Control&#xff09;&#xff0c;是一种软件设计原则&#xff0c;用于减少计算机代码之间的耦合度。控制反转的核心思想是将传统程序中对象的创建和绑定由程序代码直接控制转移到…

阿里云幻兽帕鲁服务器4核16G配置报价

自建幻兽帕鲁服务器租用价格表&#xff0c;2024阿里云推出专属幻兽帕鲁Palworld游戏优惠服务器&#xff0c;配置分为4核16G和4核32G服务器&#xff0c;4核16G配置32.25元/1个月、10M带宽66.30元/1个月、4核32G配置113.24元/1个月&#xff0c;4核32G配置3个月339.72元。ECS云服务…

C++(搜索二叉树)

目录 前言&#xff1a; 1.二叉搜索树 1.1二叉搜索树的定义 1.2二叉搜索树的特点 2.二叉搜索树的实现 2.1框架 2.2查找 2.3插入 2.4删除 1.右子树为空 2.左子树为空 3.左右都不为空 3.递归版本 3.1前序遍历 3.2中序遍历 3.3后续遍历 3.4查找&#xff08;递…