compress/obfuscate JavaScript 可以用括号表示吗?
Can bracket notation be used to compress/obfuscate JavaScript?
这主要是出于学术原因,但我很好奇广泛使用括号表示法而不是点表示法是否有任何问题。
一些可能的应用可能包括:
- 通过常用方法或属性的重复数据删除进一步压缩
- 通过使去最小化代码仍然难以understand/follow
进一步混淆
我知道 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;
})();
为访问方法生成"constants":
var createElement = "createElement";
var setAttribute = "setAttribute";
var appendChild = "appendChild";
使用这些常量将点符号调用替换为括号符号调用
child = document[createElement]('div');
child[setAttribute]('foo', 'bar');
parent[appendChild](child);
现在 mangler 可以将变量名和方法调用减少为单个字符
var c = "createElement";
var s = "setAttribute";
var a = "appendChild";
child = document[c]('div');
child[s]('foo', 'bar');
parent[a](child);
缩小后,这个人为设计的示例的大小减少了 44%。
显然这不是手动完成的事情;它可能应该针对更常用的 properties/methods.
的 AST 来完成
全面使用括号符号有什么用吗?
我发现一些 SO 问题说它们是 pretty much the same, while some claim bracket notation involving a variable lookup cannot be JIT optimized and is much slower. And then there are 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[name]
:
if (obj[name] !== "value 257") throw "Error in test";
Chrome、Firefox、IE11 上的运行结果:
在 Chrome (V8) 和 IE11 (JScript) 上,性能都大幅降低。 Firefox (SpiderMonkey) 受到影响,但没有那么严重。
这主要是出于学术原因,但我很好奇广泛使用括号表示法而不是点表示法是否有任何问题。
一些可能的应用可能包括:
- 通过常用方法或属性的重复数据删除进一步压缩
- 通过使去最小化代码仍然难以understand/follow 进一步混淆
我知道 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;
})();
为访问方法生成"constants":
var createElement = "createElement"; var setAttribute = "setAttribute"; var appendChild = "appendChild";
使用这些常量将点符号调用替换为括号符号调用
child = document[createElement]('div'); child[setAttribute]('foo', 'bar'); parent[appendChild](child);
现在 mangler 可以将变量名和方法调用减少为单个字符
var c = "createElement"; var s = "setAttribute"; var a = "appendChild"; child = document[c]('div'); child[s]('foo', 'bar'); parent[a](child);
缩小后,这个人为设计的示例的大小减少了 44%。
显然这不是手动完成的事情;它可能应该针对更常用的 properties/methods.
的 AST 来完成全面使用括号符号有什么用吗?
我发现一些 SO 问题说它们是 pretty much the same, while some claim bracket notation involving a variable lookup cannot be JIT optimized and is much slower. And then there are 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[name]
:
if (obj[name] !== "value 257") throw "Error in test";
Chrome、Firefox、IE11 上的运行结果:
在 Chrome (V8) 和 IE11 (JScript) 上,性能都大幅降低。 Firefox (SpiderMonkey) 受到影响,但没有那么严重。