括号表示法可用于压缩/混淆JavaScript吗?

时间:2015-02-17 10:12:31

标签: 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);
    
  4. 缩小后,这个人为的例子缩小了44%。

    显然,这不是手动完成的事情;它可能应该针对更常用的属性/方法针对AST进行。

    是否存在使用括号表示法的任何内容?

    我发现一些SO问题说它们是pretty much the same,而一些声称包含变量查找的括号表示法不能进行JIT优化而且速度要慢得多。然后有microbenchmarks这两种显示,所以我不确定它的确在哪里。

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

1 个答案:

答案 0 :(得分:0)

它确实会导致某些引擎出现JIT问题。不会混淆十几件事的much simpler benchmark证明了这一点(如下)。所以你可以这样做,但是你必须接受性能成本,这在一些引擎上很重要(例如,Chrome的属性访问速度降低了约64%; ~86%< / strong>在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[name]

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

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

enter image description here

在Chrome(V8)和IE11(JScript)上,性能大幅降低。 Firefox(SpiderMonkey)受到了影响,但并不那么糟糕。