javascript - 为什么闭包编译器坚持添加更多字节?

标签 javascript google-closure-compiler minify

如果我给 Closure Compiler 这样的东西:

window.array = '0123456789'.split('');

它将其“编译”为:

window.array="0,1,2,3,4,5,6,7,8,9".split(",");

现在你可以看出,它更大了。闭包编译器这样做有什么原因吗?

最佳答案

认为这就是正在发生的事情,但我绝不确定......

导致插入逗号的代码是 PeepholeSubstituteAlternateSyntax.java 中的 tryMinimizeStringArrayLiteral .

该方法包含可能具有较低 Huffman encoding 的字符列表。 ,因此比其他字符更适合拆分。如果您尝试这样的操作,您可以看到结果:

"a b c d e f g".split(" "); //Uncompiled, split on spaces
"a,b,c,d,e,f,g".split(","); //Compiled, split on commas (same size)

编译器会将您尝试拆分的字符替换为它认为有利的字符。它通过迭代字符串的字符并找到字符串中未出现的最有利的分割字符来实现这一点:

// These delimiters are chars that appears a lot in the program therefore
// probably have a small Huffman encoding.
NEXT_DELIMITER: for (char delimiter : new char[]{',', ' ', ';', '{', '}'}) {
  for (String cur : strings) {
    if (cur.indexOf(delimiter) != -1) {
      continue NEXT_DELIMITER;
    }
  }
  String template = Joiner.on(delimiter).join(strings);
  //...
}

在上面的代码片段中,您可以看到编译器声称最适合分割的字符数组。逗号在前(这就是为什么在上面的空格示例中,空格已被逗号替换)。

我相信在要分割的字符串是空字符串的情况下插入逗号可能只是一个疏忽。对于这种情况似乎没有任何特殊处理,因此它的处理方式与任何其他 split 调用类似,每个字符都与上面代码片段中显示的数组中的第一个适当的字符连接。

<小时/>

编译器如何处理 split 方法的另一个示例:

"a,;b;c;d;e;f;g".split(";"); //Uncompiled, split on semi-colons
"a, b c d e f g".split(" "); //Compiled, split on spaces

这次,由于原始字符串已经包含逗号(并且我们不想在逗号字符上进行分割),因此无法从低霍夫曼编码字符数组中选择逗号,因此下一个选择最佳选择(空格)。

<小时/>

更新

经过进一步研究,这绝对不是一个错误。这种行为实际上是设计使然,在我看来,这是一个非常聪明的小优化,因为闭包编译器往往更看重编译代码的速度而不是大小。

上面我多次提到了霍夫曼编码。霍夫曼编码算法,解释起来非常简单,为出现在要编码的文本中的每个字符分配一个权重。权重基于每个字符出现的频率。这些频率用于构建二叉树,最常见的字符位于根。这意味着最常见的字符可以更快地解码,因为它们更接近树的根。

而且由于 Huffman 算法是 gzip 使用的 DEFLATE 算法的很大一部分。因此,如果您的网络服务器配置为使用 gzip,您的用户将受益于这种巧妙的优化。

关于javascript - 为什么闭包编译器坚持添加更多字节?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10210421/

相关文章:

javascript - 一旦 promise 实现就渲染 [React Native]

javascript - D3,添加新组元素和行时遇到问题

javascript - Shopify API 访问已被禁用

javascript - 使用 yuicompressor 将多个 js 文件压缩为一个

javascript - 缩小内联脚本

javascript - 具有更灵活许可的 ExtJS 网格替代品?

Javascript 模块模式、原型(prototype)和 Google Closure

javascript - 谷歌闭包编译器中的高级编译

javascript - google-closure-compiler 基本流程示例

css - 在网站的不同部分将 CSS 文件组合成缩小的 "chunks"是否明智?