【问题标题】:Variables in Google ClosureGoogle 闭包中的变量
【发布时间】:2013-04-06 07:19:29
【问题描述】:

http://closure-compiler.appspot.com/home

(function(){

var somevar = 'somevar';

this.each(function(){
var minify_var = {
  method1: somevar + '1', 
  method2: somevar + '2',
  method3: somevar + '3',
  method4: somevar + '4',
  method5: somevar + '5'
};

alert(minify_var);
});

})();

这样的代码被缩小为:

(function(){this.each(function(){alert({method1:"somevar1",method2:"somevar2",method3:"somevar3",method4:"somevar4",method5:"somevar5"})})})();

长度(+11 个符号)肯定大于:

(function(){var a="somevar";this.each(function(){alert({method1:a+"1",method2:a+"2",method3:a+"3",method4:a+"4",method5:a+"5"})})})();

问题是,我们有两个变量,但得到了一个。

其实对于小脚本来说还不错,但是对于大脚本来说可能会受到伤害。

添加了第一个变量以使缩小的代码更小,但 google 忽略了它。

它也忽略了大多数类似的其他尺寸优化技巧。

可以修复吗?

这个问题是关于 Google Closure,而不是 JavaScript 模式。

【问题讨论】:

  • 我猜 Closure 是为遵循更好实践的代码而设计的。您可能应该编写可读的代码并让它缩小它。
  • @dystroy 这不是一个更好的做法,似乎它只是合并了只读变量
  • 嗯,这简化了代码并避免了无用的运行时计算,这看起来很聪明。过早缩小是万恶之源……

标签: javascript jquery minify google-closure


【解决方案1】:

编译器假定文件在提供给用户时会被压缩,因此它会针对压缩的文件大小而不是未压缩的大小进行优化。

我测试了两个版本的代码。

版本 A(将 a 视为全局变量可防止其在以后自动连接):

(function () {
    a = 'somevar';

    this.each(function () {
        var minify_var = {
            method1: a + '1',
            method2: a + '2',
            method3: a + '3',
            method4: a + '4',
            method5: a + '5'
        };

        alert(minify_var);
    });
})();

生成的缩小代码:

(function(){a="somevar";this.a(function(){alert({b:a+"1",c:a+"2",d:a+"3",e:a+"4",f:a+"5"})})})();

大小:97 字节(95 字节压缩)。

版本 B(同上,但 a 是一个局部变量,因此编译器会进行优化):

(function () {
    var a = 'somevar';

    this.each(function () {
        var minify_var = {
            method1: a + '1',
            method2: a + '2',
            method3: a + '3',
            method4: a + '4',
            method5: a + '5'
        };

        alert(minify_var);
    });
})(); 

生成的缩小代码:

(function(){this.a(function(){alert({b:"somevar1",c:"somevar2",d:"somevar3",e:"somevar4",f:"somevar5"})})})();

大小:110 字节(89 字节压缩)。


所以第二个版本在未压缩时更大,但当它被 gzip 压缩时它更小,因为变量声明消失了,gzip 将重复部分压缩到大致相同的空间,而不管重复文本有多长。

这是来自FAQ 的条目:

闭包编译器内联了我所有的字符串,这使我的代码变大了。为什么这样做?

大多数人通过查看两个未压缩的 JavaScript 文件来比较代码大小。但这是查看代码大小的一种误导方式,因为您的 JavaScript 文件不应该以未压缩的形式提供。它应该使用 gzip 压缩。

Closure Compiler 假定您正在使用 gzip 压缩。如果你不这样做,你应该这样做。配置你的服务器以压缩你的代码是你可以做的最有效和最简单的优化之一。 gzip 算法通过尝试以最佳方式对字节序列进行别名来工作。手动给字符串起别名几乎总是会使压缩后的代码变大,因为它颠覆了 gzip 自己的别名算法。 因此 Closure Compiler 将(几乎)总是尽可能内联您的字符串,因为这会使您的压缩代码更小。

【讨论】:

  • “针对压缩文件大小进行优化”——观察还是记录?
  • @JanDvorak 这是常识,因为 gzip 压缩版本在现实中很重要。我找不到明确的引用,但可以在很多地方的行之间读取:"Closure Compiler 甚至可以判断两个不同的变量何时从未同时使用,让两者共享相同的名称并确保尽可能多的变量使用非常短的名称以获得更好的 gzip 压缩。” (1) “在大多数情况下,较小的代码是更快的代码,因为下载时间通常是 Web 应用程序中最重要的速度因素。” (2)
  • 啊,这里是:"Closure Compiler 假定您使用的是 gzip 压缩。" code.google.com/p/closure-compiler/wiki/…
【解决方案2】:

各种编译器(gcc、g++、jdk 等)总是面临以下问题: “追求速度还是追求规模”

在这种情况下,关闭采取了速度方法。它认识到您在许多地方都有一个常量变量,并直接重写了该值。以下是关闭团队对此事的看法:

https://developers.google.com/closure/compiler/faq#tradeoffs

编译器是否会在我的应用程序的执行速度和下载代码大小之间进行权衡?

是的。任何优化编译器都会做出权衡。一些尺寸优化确实会引入小的速度开销。但是,闭包编译器的开发人员一直小心翼翼地不引入大量额外的运行时。一些编译器的优化甚至减少了运行时间(见下一个问题)。

编译器是否针对速度进行了优化?

在大多数情况下,更小的代码是更快的代码,因为下载时间通常是 Web 应用程序中最重要的速度因素。减少冗余的优化也加快了代码的运行时间。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2012-11-21
  • 2015-07-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-04
  • 2012-10-20
  • 2017-06-25
相关资源
最近更新 更多