
Over the past 3 months since the publication of the
previous review , almost all the minimization algorithms considered (except for the Packer ʻa) have already been updated. In addition, a new minimizer module based on Clean-css -
BundleTransformer.CleanCss - appeared in
Bundle Transformer .
In preparing this comparative review, the following readers' wishes were taken into account:
- In the previous review, the following files were used as source files:
bootstrap.css
and bootstrap.js
from Twitter Bootstrap 2.3.2 , because of which the reliability of the results was low. In the new review, the sample size was increased: 7 JS files and 5 CSS files from 10 popular Open Source projects were selected for comparison. - Now the built-in minimization of LESS and Sass preprocessors are also involved in comparing CSS minimizers.
- As you know, Bundle Transformer minimizes each file separately and then merges the minimized code into one file. This mechanism is made in order to prevent re-minimization of previously minimized files. Other similar libraries first merge code files, and then minimize this merged file. Therefore, for completeness, we will make 2 comparisons: first, we compare the effectiveness of minimizers on the files obtained by combining the minimized code, and then on the files obtained by minimizing the combined code of the files.
As in the previous review, to minimize the files we will use the modules Bundle Transformer, and to measure the size of the resulting files - the extension
YSlow .
Comparison of CSS minimizers
Let's compare the following algorithms for minimizing CSS code:
')
Table 1. Information about adapters and CSS minimization algorithms
In order to use the
LessTranslator
and
SassAndScssTranslator
as minimizers, you need to change the extensions of the original CSS files to
.less
(and
.scss
respectively) and set the
useNativeMinification
configuration property to
true
.
We will use as source files:
bootstrap.css
from Twitter Bootstrap 3.0.0jquery-ui-1.10.3.custom.css
from jQuery UI 1.10.3animate.css
from Animate.css on 08/15/2013hint.css
from Hint.css 1.3.0zocial.css
from Zocial CSS social buttons from 02.12.2012
The combined file size is 296.2 KB, and after applying GZip compression, it is 98.7 KB.
Table 2. The result of applying CSS minimization algorithms to each file separately
Adapter | Size after minimization, KB | Saving | Size after minimization with GZip compression, KB | Savings with gzip compression |
---|
in kb | at % | in kb | at % |
---|
YuiCssMinifier | 239.7 | 56.5 | 19.07 | 79.9 | 18,8 | 19.05 |
MicrosoftAjaxCssMinifier | 238.7 | 57.5 | 19.41 | 79.5 | 19.2 | 19.45 |
KryzhanovskyCssMinifier | 234.1 | 62.1 | 20.97 | 78.0 | 20.7 | 20.97 |
WgCssMinifier | - | - | - | - | - | - |
CleanCssMinifier | 240.6 | 55.6 | 18.77 | 80.2 | 18.5 | 18.74 |
LessTranslator | 240.0 | 56.2 | 18.97 | 80.0 | 18.7 | 18.95 |
SassAndScssTranslator | 241.2 | 55.0 | 18.57 | 80.4 | 18.3 | 18,54 |
Table 3. The result of applying CSS minimization algorithms to the merged file
Adapter | Size after minimization, KB | Saving | Size after minimization with GZip compression, KB | Savings with gzip compression |
---|
in kb | at % | in kb | at % |
---|
YuiCssMinifier | 239.7 | 56.5 | 19.07 | 79.9 | 18,8 | 19.05 |
MicrosoftAjaxCssMinifier | 238.7 | 57.5 | 19.41 | 79.5 | 19.2 | 19.45 |
KryzhanovskyCssMinifier | 232.4 | 63,8 | 21.54 | 77.4 | 21.3 | 21.58 |
WgCssMinifier | - | - | - | - | - | - |
CleanCssMinifier | 240.6 | 55.6 | 18.77 | 80.2 | 18.5 | 18.74 |
LessTranslator | 240.0 | 56.2 | 18.97 | 80.0 | 18.7 | 18.95 |
SassAndScssTranslator | 241.2 | 55.0 | 18.57 | 80.4 | 18.3 | 18,54 |
Fig. 1. Savings due to the use of CSS minimization algorithms (in percent)
From the graph it is clearly seen that, like last time, the best result was shown by the CSSO Minimizer (CSS Optimizer) from
Yandex . But it was not done without a fly in the ointment: an additional gain of 0.57% when compressing the merged file was obtained by deleting two comments like:
/*! - */
/*! - */
. As a rule, such comments contain information about the version of the library and its developers. CSSO leaves only the first such comment, and removes the rest (see UPD2).
Microsoft Ajax CSS Minifier again showed a good result compared to its main competitor - YUI CSS Compressor for .Net.
Most of all I was surprised by the newcomer - Clean-css from
Goal Smashers! . From the CSS minimizer that is so popular in the Node.js community (Clean-css is used by the
grunt-contrib-cssmin package ), I expected a greater degree of compression. By minimizing efficiency, it is located between the built-in minimizers of the LESS and Sass preprocessor.
The new version of the structural minimizer from
Microsoft - WebGrease Semantic CSS Minifier still contains critical errors:
- Cannot process the
@charset
directive and the @-o-keyframes
rule. - Zero fractional values that are less than one.
Therefore, WebGrease Semantic CSS Minifier again out of the fight.
It is practically not visible from the graph that the files obtained by minimizing the file with the merged code (the exception is the file processed with CSSO) are slightly smaller in size than the files collected from the separately minimized files. The smaller size of these files is due to two reasons:
- The extra line breaks that separate the code for individual files have been removed.
- Several
@charset
directives were merged into one.
Therefore, we can conclude that minimizing a file with merged code practically does not give a gain in file size.
JS-code minimizers comparison
Let's compare the following JS code minimization algorithms:
Table 4. Information about adapters and JS code minimization algorithms
If you have already noticed, then the
EdwardsJsMinifier
minimizing adapter is missing from the list above. As the minimization algorithm of Packer 3.0 supported by it has not changed since 2007, I decided not to include it in this review.
We will use as source files:
bootstrap.js
from Twitter Bootstrap 3.0.0jquery-ui-1.10.3.custom.js
from jQuery UI 1.10.3MicrosoftAjax.debug.js
from Microsoft AJAX Framework 4.0.0.0knockout-2.3.0.debug.js
of Knockout 2.3.0jsrender.js
from JsRender 1.0.0-betalinq.js
from LINQ for JavaScript 2.2.0.2moment.js
from Moment.js 2.1.0
The combined file size is 1218.9 KB, and after applying GZip-compression - 406.3 KB.
Table 5. The result of applying the JS minimization algorithms to each file separately
Adapter | Size after minimization, KB | Saving | Size after minimization with GZip compression, KB | Savings with gzip compression |
---|
in kb | at % | in kb | at % |
---|
CrockfordJsMinifier | 713.5 | 505.4 | 41.46 | 237.8 | 168,5 | 41.47 |
YuiJsMinifier | 593.0 | 625.9 | 51.35 | 197.6 | 208.7 | 51.37 |
ClosureLocalJsMinifier | 525.4 | 693.5 | 56.90 | 175.1 | 231.2 | 56.90 |
MicrosoftAjaxJsMinifier | 527.7 | 691.2 | 56,71 | 175.9 | 230.4 | 56,71 |
UglifyJsMinifier | 531.1 | 687.8 | 56,43 | 177.0 | 229.3 | 56,44 |
Table 6. The result of applying JS minimization algorithms to the merged file
Adapter | Size after minimization, KB | Saving | Size after minimization with GZip compression, KB | Savings with gzip compression |
---|
in kb | at % | in kb | at % |
---|
CrockfordJsMinifier | 713,4 | 505.5 | 41.47 | 237.8 | 168,5 | 41.47 |
YuiJsMinifier | 593.0 | 625.9 | 51.35 | 197.6 | 208.7 | 51.37 |
ClosureLocalJsMinifier | 525.3 | 693.6 | 56.90 | 175.1 | 231.2 | 56.90 |
MicrosoftAjaxJsMinifier | 527.7 | 691.2 | 56,71 | 175.9 | 230.4 | 56,71 |
UglifyJsMinifier | 533.1 | 685,8 | 56,26 | 177.7 | 228.6 | 56,26 |
Fig. 2. Savings due to the use of JS minimization algorithms (in percent)
From the above data it is clear that the minimizer Closure Compiler from
Google is still in the first place.
Microsoft Ajax JS Minifier this time overtook UglifyJS and rightfully took second place.
In general, UglifyJS surprised me a lot by the fact that while minimizing a file with merged code, the size of the resulting file not only did not decrease, but on the contrary increased. That says about some flaws in the algorithm.
YUI JS Compressor for .Net is far behind the top three minimizers, which indicates that its algorithm is outdated.
Despite the fact that JSMin is still evolving, the principles laid down in it remain the same: no interference with the script logic, only the deletion of comments and whitespace. Therefore, in this review, JSMin is not even a participant, but serves as a lower bound.
As in the case with CSS minimizers, we got a very small gain from minimizing the file with the combined code.
Conclusion
Like last time, the search engine giants Yandex and Google won the battle of minimizers. It's nice to know that the best CSS minimizer was created in a Russian company.
Despite serious problems with the WebGrease Semantic CSS Minifier minimizer, Microsoft has made great strides in developing the Microsoft Ajax Minifier family of minimizers.
All source and minimized files are available at -
https://www.dropbox.com/s/k232cloh87sn9pr/css-and-js-minifiers-sep-2013-files.zip .
UPD1: Redid graphics to display percentages.
UPD2: With regard to the "fly in the ointment" in CSSO, a
comment was received
from Sergey Kryzhanovsky (developer of CSSO). In fact, this is not a flaw, but simply a feature of structural minimization: when changing the structure of the style sheet, such comments can be separated from the code to which they relate, and simply “hang” in the style sheet. Therefore, only the first comment is saved. Here the situation is similar to the similar situation with Closure Compiler, which removes all comments in general at structural minimization of JS code.
UPD3: I tried to test with CSS minimizer
Closure Stylesheets . First I tested the latest available version of the binary —
closure-stylesheets-20111230.jar and got an error while minimizing the
bootstrap.css
file. Then I collected the latest version of the source code (commit
86bb800d79a3 ) and again got an error while minimizing the
bootstrap.css
file:
Compiler parsing error: Parse error in C:\!closure-stylesheets\bootstrap.css at line 1658 column 19: margin-top: 1px \9; ^ com.google.common.css.compiler.ast.GssParserException: Parse error in C:\!closure-stylesheets\bootstrap.css at line 1658 column 19: margin-top: 1px \9; ^ at com.google.common.css.compiler.ast.GssParserCC.parse(GssParserCC.java:176) at com.google.common.css.compiler.ast.GssParser.parse(GssParser.java:46) at com.google.common.css.compiler.commandline.DefaultCommandLineCompiler.parseAndPrint(DefaultCommandLineCompiler.java:104) at com.google.common.css.compiler.commandline.DefaultCommandLineCompiler.compile(DefaultCommandLineCompiler.java:94) at com.google.common.css.compiler.commandline.DefaultCommandLineCompiler.execute(DefaultCommandLineCompiler.java:129) at com.google.common.css.compiler.commandline.ClosureCommandLineCompiler.executeJob(ClosureCommandLineCompiler.java:290) at com.google.common.css.compiler.commandline.ClosureCommandLineCompiler.main(ClosureCommandLineCompiler.java:356) Caused by: com.google.common.css.compiler.ast.ParseException: Encountered " <BAD_TOKEN> "\\ "" at line 1658, column 19. Was expecting one of: ";" ... "/" ... "=" ... "}" ... "," ... <S> ... <IMPORTANT_SYM> ... <ATKEYWORD> ... at com.google.common.css.compiler.ast.GssParserCC.generateParseException(GssParserCC.java:3756) at com.google.common.css.compiler.ast.GssParserCC.jj_consume_token(GssParserCC.java:3635) at com.google.common.css.compiler.ast.GssParserCC.ruleSet(GssParserCC.java:464) at com.google.common.css.compiler.ast.GssParserCC.block(GssParserCC.java:2856) at com.google.common.css.compiler.ast.GssParserCC.start(GssParserCC.java:2903) at com.google.common.css.compiler.ast.GssParserCC.parse(GssParserCC.java:174) ... 6 more
In addition, I also tried to minimize
jquery-ui-1.10.3.custom.css
and
animate.css
, and again received errors.
Therefore, Closure Stylesheets, as well as WebGrease Semantic CSS Minifier, cannot participate in the comparative tests of this review.
UPD4: Added a link to the archive with the source and minimized files -
https://www.dropbox.com/s/k232cloh87sn9pr/css-and-js-minifiers-sep-2013-files.zip .
Poll
In conclusion, I suggest you take part in the survey. If you did not find your minimizer in the list of response options, then select the option `Other`, and then indicate its name and the address of the developer site in the comments.