Variables in Google Closure

2019-05-19 04:00发布

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);
});

})();

Code like this is minified to:

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

Which is definitely bigger at length (+11 symbols) than:

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

The problem is, we had two variables, but got one instead.

Actually it's not bad for a small scripts, but can hurt on a big ones.

First variable is added to make minified code a bit smaller, but google ignores it.

It also ignores most of the other size optimization tricks like this.

Can it be fixed?

This question is about Google Closure, not JavaScript patterns.

2条回答
看我几分像从前
2楼-- · 2019-05-19 04:18

Compilers of all kinds (gcc, g++, jdk, etc) always face these kinds of problems: "strive for speed or strive for size"

In this case, closure has taken the speed approach. It recognized that you had a constant variable in many places and rewrote the value directly. Here is what the closure team says about this matter:

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

Does the compiler make any trade-off between my application's execution speed and download code size?

Yes. Any optimizing compiler makes trade-offs. Some size optimizations do introduce small speed overheads. However, the Closure Compiler's developers have been careful not to introduce significant additional runtime. Some of the compiler's optimizations even decrease runtime (see next question).

Does the compiler optimize for speed?

In most cases smaller code is faster code, since download time is usually the most important speed factor in web applications. Optimizations that reduce redundancies speed up the run time of code as well.

查看更多
3楼-- · 2019-05-19 04:32

The compiler assumes that the file will be gzipped when it's served to the user, so it optimizes for the compressed file size instead of the uncompressed size.

I tested with two versions of the code.

Version A (treating a as a global variable prevents it from being automatically concatenated later):

(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);
    });
})();

Resulting minified code:

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

Size: 97 bytes (95 bytes gzipped).

Version B (the same as above, but a is a local variable so the compiler does its optimizations):

(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);
    });
})(); 

Resulting minified code:

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

Size: 110 bytes (89 bytes gzipped).


So the second version is larger uncompressed, but when it's gzipped it's smaller because the variable declaration is gone and gzip compresses repetitive parts to roughly the same space regardless of how long the repeated text is.

Here's an entry from the FAQ:

Closure Compiler inlined all my strings, which made my code size bigger. Why did it do that?

Most people compare code size by looking at two uncompressed JavaScript files. But that's a misleading way to look at code size, because your JavaScript files should not be served uncompressed. It should be served with gzip compression.

Closure Compiler assumes that you are using gzip compression. If you do not, you should. Configuring your server to gzip your code is one of the most effective and easiest optimizations that you can possibly do. The gzip algorithm works by trying to alias sequences of bytes in an optimal way. Aliasing strings manually almost always makes the compressed code size bigger, because it subverts gzip's own algorithm for aliasing. So Closure Compiler will (almost) always inline your strings when it can, because that will make your compressed code smaller.

查看更多
登录 后发表回答