您的位置:首页 > 房产 > 建筑 > 潮州专业网站建设制作_设计店名logo_外链推广网站_营销运营主要做什么

潮州专业网站建设制作_设计店名logo_外链推广网站_营销运营主要做什么

2025/2/25 23:18:26 来源:https://blog.csdn.net/Bruce__taotao/article/details/145829990  浏览:    关键词:潮州专业网站建设制作_设计店名logo_外链推广网站_营销运营主要做什么
潮州专业网站建设制作_设计店名logo_外链推广网站_营销运营主要做什么

参考链接

1. esbuild
2. terser

前言

Terser 为什么比 esbuild 压缩体积更小?原理分析

terser 之所以比 esbuild 产生的打包体积更小,主要是因为 它提供了更高级的优化手段,包括 作用域折叠(Scope Hoisting)、变量提升、代码混淆、AST 级别优化、更多高级压缩策略,而 esbuild 的压缩主要是 简单的语法转换和删除无用空格/换行符,缺少深入的 AST 级别优化。

下面我们从 代码优化原理、构建方式、作用域分析、Tree Shaking 等方面进行深入分析。


1. AST 层面的压缩差异

AST(Abstract Syntax Tree)抽象语法树

terseresbuild 都基于 AST(抽象语法树)进行代码优化,但 terser 在 AST 级别执行了更多高级优化,而 esbuild 主要做基本的 minify(缩小代码)。

示例

假设我们有这样一段 JavaScript 代码:

function add(a, b) {return a + b;
}console.log(add(1, 2));

Esbuild 压缩

详细分析

1. 词法分析(Lexical Analysis)
  • esbuildlexer 会解析代码,将其转换成 Token 流,例如:
    function → Token{Type: FUNCTION}
    add → Token{Type: IDENTIFIER}
    ( → Token{Type: PUNCTUATION}
    a → Token{Type: IDENTIFIER}
    b → Token{Type: IDENTIFIER}
    return → Token{Type: RETURN}
    a + b → Token{Type: BINARY_EXPRESSION}
    
  • 这个过程只是将代码拆分成可解析的最小单元。
2. 语法解析(Parsing)
  • esbuildjs_parser 中将 Token 解析为 AST(抽象语法树)
    {"type": "FunctionDeclaration","name": "add","params": ["a", "b"],"body": {"type": "ReturnStatement","argument": {"type": "BinaryExpression","operator": "+","left": "a","right": "b"}}
    }
    
  • console.log(add(1, 2)) 也被解析成 AST 结构。
3. 代码优化(Minification)

js_printer 处理阶段:

  • 移除空格、换行
  • 保留 function add 结构(因为 esbuild 不是一个高级压缩工具)
  • 不会执行函数折叠(不会把 add(1,2) 直接计算成 3

所以最终输出:

function add(a,b){return a+b}console.log(add(1,2));

为什么 esbuild 没有优化成 console.log(3);

相比 terseresbuild 不会执行高级优化,例如:

  • 常量折叠(Constant Folding):计算 add(1, 2) 并替换成 console.log(3)
  • 函数内联(Inlining):如果 add() 只在一个地方调用,它可以被展开成 console.log(1 + 2)
  • Dead Code Elimination(DCE,死代码消除):如果 add() 没有被调用,它会直接删除 add()

terser 会进行这些优化:

  • terser 发现 add(1,2) 这个调用是 纯函数(pure function),可以直接计算并替换为 console.log(3),去掉 add 函数。
console.log(3);

关键优化点:

  • terser 直接 折叠函数调用结果(常量折叠),消除了 add() 这个函数,从而减少代码体积。

2. Terser 的高级优化机制

1) 作用域折叠(Scope Hoisting)

作用域折叠可以 减少作用域的嵌套,将函数或变量合并到更紧凑的作用域中。

示例

原始代码:

function outer() {function inner() {console.log('Hello');}return inner;
}
outer()();
esbuild 压缩
function outer(){return function(){console.log("Hello")}}outer()();
  • 依然保留了 outer 这个作用域。
terser 压缩
console.log("Hello");
  • terser 直接移除了 outer,因为它的唯一作用是返回 inner,可以省略掉。

作用:

  • 减少作用域层级,降低闭包开销,提高运行时性能。

2) 变量提升和合并

terser 会尽可能减少变量声明的数量,合并多个变量定义,从而减少代码大小。

示例

原始代码:

let a = 1;
let b = 2;
let c = a + b;
console.log(c);
esbuild 压缩
let a=1,b=2,c=a+b;console.log(c);
  • esbuild 只是合并了 let 语句,但没有进一步优化。
terser 压缩
console.log(3);
  • terser 发现 c 是常量,直接替换掉,省略了变量声明。

3) 常量折叠(Constant Folding)

terser 能够分析并消除计算结果为常量的代码,而 esbuild 没有类似的优化。

示例

原始代码:

const a = 100;
const b = a * 2;
console.log(b);
esbuild 压缩
const a=100,b=a*2;console.log(b);
terser 压缩
console.log(200);
  • terser 发现 b 是常量,直接用 200 替换掉 b,从而减少代码体积。

4) 死代码消除(Dead Code Elimination)

terser 可以彻底删除不会被执行的代码,而 esbuild 只能删除一些最基本的未引用变量。

示例

原始代码:

function test() {if (false) {console.log("This will never run");}
}
test();
esbuild 压缩
function test(){}test();
  • esbuild 只删除了 if 语句,但 test() 这个函数还在。
terser 压缩
  • terser 发现 test() 没有任何作用,直接删掉整个函数调用。

5) Tree Shaking(摇树优化)

Tree Shaking 主要是用于删除未使用的模块terser 在这方面比 esbuild 更激进。

示例

原始代码:

import { unusedFunc, usedFunc } from './module.js';
usedFunc();
esbuild 压缩
import { usedFunc } from "./module.js"; usedFunc();
  • esbuild 只是去掉了 unusedFunc 的导入,但代码本身依然保留 import 语句。
terser 压缩
import { usedFunc } from "./module.js"; usedFunc();
  • terser 在与 rollup 结合时,可以进一步优化 整个 import 语句,如果 usedFunc 也可以被内联,则可能直接删除 import

3. esbuild 的设计取舍

esbuild 的目标是快速打包,而不是极致的压缩,因此做了一些权衡:

  • 不做复杂的 AST 分析(导致一些优化缺失)
  • 不执行复杂的代码混淆(可读性更强)
  • 优先优化构建速度(10~100 倍快)

相比之下,terser 作为一个专业的压缩器,使用了:

  • 深度 AST 分析
  • 更激进的 Tree Shaking
  • 代码混淆
  • 优化作用域和常量折叠

这些优化让 terser 产出的代码体积更小,但牺牲了构建速度。


4. 总结

特性esbuildterser
构建速度快(10-100 倍)
代码压缩基本压缩(去空格、缩变量名)深度优化(作用域折叠、Tree Shaking、死代码消除)
Tree Shaking一般更激进
变量合并基本合并常量折叠+变量内联
代码混淆支持
适用场景开发环境 & 速度优先生产环境 & 体积优化优先

如果你的项目 构建速度是瓶颈,继续使用 esbuild;如果 最终代码体积更重要,建议切换到 terser 进行压缩优化。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com