javascript - 括号表示法可以用来压缩/混淆 JavaScript 吗?

标签 javascript performance compression minify uglifyjs2

这主要是出于学术原因,但我很好奇广泛使用括号表示法而不是点表示法是否有任何问题。

一些可能的应用可能包括:

  • 通过对常用方法或属性进行重复数据删除来进一步压缩
  • 通过使去压缩代码仍然难以理解/遵循来进一步混淆

我知道 gzip 压缩可能会使重复数据删除的好处变得无用,并且 JavaScript 的混淆可能是徒劳的,因此我真的只是对这种技术出于学术目的的利弊感到好奇。

考虑对该代码进行以下一系列转换:

(function () {
    var parent, child;
    parent = document.body;

    child = document.createElement('div');
    child.setAttribute('foo', 'bar');
    parent.appendChild(child);
    parent = child;

    child = document.createElement('div');
    child.setAttribute('foo', 'bar');
    parent.appendChild(child);
    parent = child;

    child = document.createElement('div');
    child.setAttribute('foo', 'bar');
    parent.appendChild(child);
    parent = child;

    child = document.createElement('div');
    child.setAttribute('foo', 'bar');
    parent.appendChild(child);
    parent = child;

    child = document.createElement('div');
    child.setAttribute('foo', 'bar');
    parent.appendChild(child);
    parent = child;

    child = document.createElement('div');
    child.setAttribute('foo', 'bar');
    parent.appendChild(child);
    parent = child;

    child = document.createElement('div');
    child.setAttribute('foo', 'bar');
    parent.appendChild(child);
    parent = child;

    child = document.createElement('div');
    child.setAttribute('foo', 'bar');
    parent.appendChild(child);
    parent = child;
})();
  1. 生成用于访问方法的“常量”:

    var createElement = "createElement";
    var setAttribute = "setAttribute";
    var appendChild = "appendChild";
    
  2. 使用这些常量将点表示法调用替换为括号表示法调用

    child = document[createElement]('div');
    child[setAttribute]('foo', 'bar');
    parent[appendChild](child);
    
  3. 现在,mangler 可以将变量名称和方法调用减少为单个字符

    var c = "createElement";
    var s = "setAttribute";
    var a = "appendChild";
    
    child = document[c]('div');
    child[s]('foo', 'bar');
    parent[a](child);
    

缩小后,这个设计示例的大小减少了 44%。

显然这不是手动完成的事情;而是需要手动完成。它可能应该针对 AST 和更常用的属性/方法来完成。

全面使用括号表示法有什么作用吗?

我发现了一些问题,说它们是 pretty much the same ,而某些涉及变量查找的声明括号表示法无法进行 JIT 优化,并且速度要慢得多。然后还有microbenchmarks两者都显示,所以我不太确定它到底在哪里。

我确实知道UglifyJS2 compressor options默认情况下优化属性访问,执行相反的操作:将括号表示法转换为点表示法。我只是不知道其背后的原因,除非它真的只是为了节省 3 个额外的字符。

最佳答案

它确实会导致某些引擎出现 JIT 问题。一个much simpler benchmark这并没有混淆十几件事证明了这一点(如下)。所以你可以做到这一点,但你必须接受性能成本,这对于某些引擎来说非常重要(例如,在 Chrome 上将属性访问速度降低约 64%;~86% 在 IE11 上,在我下面的简单测试中)。

准备工作:

var obj = {};
var i;
for (i = 0; i < 1000; ++i) {
    obj['prop' + i] = 'value ' + i;
}
var name = "prop257";

测试obj.prop257:

if (obj.prop257 !== "value 257") throw "Error in test";

测试obj[名称]:

if (obj[name] !== "value 257") throw "Error in test";

在 Chrome、Firefox、IE11 上运行的结果:

enter image description here

在 Chrome (V8) 和 IE11 (JScript) 上,性能都会急剧下降。 Firefox (SpiderMonkey) 受到了影响,但没有那么严重。

关于javascript - 括号表示法可以用来压缩/混淆 JavaScript 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28559520/

相关文章:

C++重复间接访问与直接访问

python - Python 的 DXT 压缩

javascript - 如何在路由路径中添加 connect-multiparty?

javascript - 在 javascript 中验证或读取远程图像类型

c# - Nhibernate 多列延迟加载

android - 使用 libgdx 绘制大背景图像 - 最佳实践?

http - 批量请求 MIME 类型的 IIS 压缩设置 'multipart/mixed'

algorithm - 提供随机访问的整数序列压缩

javascript - Highcharts 3.0 单独的导出按钮

javascript - 使用 account-ui 包创建用户时如何添加 user.profile?