![Логотипы модулей-минимизаторов из Bundle Transformer](https://habrastorage.org/getpro/habr/post_images/f19/2be/e7b/f192bee7b3bef80c35dcb45f24bb448f.png)
За прошедшие, с момента публикации предыдущего обзора, 3 месяца уже успели обновиться почти все рассмотренные алгоритмы минимизации (кроме, Packer`а). Кроме того в Bundle Transformer появился новый модуль-минимизатор на базе Clean-css — BundleTransformer.CleanCss.
При подготовке данного сравнительного обзора были учтены следующие пожелания читателей:
- В предыдущем обзоре в качестве исходных файлов использовались:
bootstrap.css
иbootstrap.js
из Twitter Bootstrap 2.3.2, из-за чего достоверность результатов была низкой. В новом же обзоре размер выборки был увеличен: для сравнения были отобраны 7 JS-файлов и 5 CSS-файлов из 10 популярных Open Source-проектов. - Теперь в сравнении минимизаторов CSS-кода также участвуют встроенные средства минимизации препроцессоров LESS и Sass.
- Как известно, Bundle Transformer минимизирует каждый файл по отдельности и затем производит объединение минимизированного кода в один файл. Данный механизм сделан для того, чтобы предотвратить повторную минимизацию предварительно минимизированных файлов. Другие аналогичные библиотеки сначала объединяют код файлов, а затем минимизируют этот объединенный файл. Поэтому для полноты картины мы произведем 2 сравнения: сначала сравним эффективность минимизаторов на файлах, полученных путем объединения минимизированного кода, а затем на файлах, полученных путем минимизации объединенного кода файлов.
Как и в предыдущем обзоре, для минимизации файлов мы будем использовать модули Bundle Transformer, а для измерения размеров полученных файлов – расширение YSlow.
Сравнение минимизаторов CSS-кода
Сравним следующие алгоритмы минимизации CSS-кода:
Таблица 1. Информация об адаптерах и алгоритмах минимизации CSS-кода
Адаптер | Алгоритм минимизации | Сайт исходной библиотеки |
---|---|---|
YuiCssMinifier |
YUI CSS Compressor for .Net 2.3.0.0 | http://yuicompressor.codeplex.com |
MicrosoftAjaxCssMinifier |
Microsoft Ajax CSS Minifier 4.97 | http://ajaxmin.codeplex.com |
KryzhanovskyCssMinifier |
CSSO 1.3.8 | http://github.com/css/csso |
WgCssMinifier |
WebGrease Semantic CSS Minifier 1.5.2 | http://webgrease.codeplex.com |
CleanCssMinifier |
Clean-css 1.1.1 | http://github.com/GoalSmashers/clean-css |
LessTranslator |
LESS 1.4.2 (режим сжатия соответствует настройкам исходной библиотеки с опцией compress равной true ) |
http://lesscss.org |
SassAndScssTranslator |
Sass 3.2.10 (режим сжатия соответствует настройкам исходной библиотеки с опцией :style равной compressed ) |
http://sass-lang.com |
Для того, чтобы использовать адаптеры-трансляторы
LessTranslator
и SassAndScssTranslator
в качестве минимизаторов, нужно изменить расширения исходных CSS-файлов на .less
(и .scss
соответсвенно) и присвоить конфигурационному свойству useNativeMinification
значение равное true
.В качестве исходных файлов мы будем использовать:
bootstrap.css
из Twitter Bootstrap 3.0.0jquery-ui-1.10.3.custom.css
из jQuery UI 1.10.3animate.css
из Animate.css от 15.08.2013hint.css
из Hint.css 1.3.0zocial.css
из Zocial CSS social buttons от 02.12.2012
Размер объединенного файла составляет 296,2 КБ, а после применения GZip-сжатия — 98,7 КБ.
Таблица 2. Результат применения алгоритмов CSS-минимизации к каждому файлу по отдельности
Адаптер | Размер после минимизации, КБ | Экономия | Размер после минимизации с GZip-сжатием, КБ | Экономия при GZip-сжатии | ||
---|---|---|---|---|---|---|
в КБ | в % | в КБ | в % | |||
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 |
Таблица 3. Результат применения алгоритмов CSS-минимизации к объединенному файлу
Адаптер | Размер после минимизации, КБ | Экономия | Размер после минимизации с GZip-сжатием, КБ | Экономия при GZip-сжатии | ||
---|---|---|---|---|---|---|
в КБ | в % | в КБ | в % | |||
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 |
![Диаграмма эффективности алгоритмов CSS-минимизации](https://habrastorage.org/getpro/habr/post_images/4e8/e0b/f69/4e8e0bf693f91f89e23703fe2f76cbf7.png)
Рис. 1. Экономия за счет использования алгоритмов CSS-минимизации (в процентах)
Из графика хорошо видно, что, как и в прошлый раз, наилучший результат показал минимизатор CSSO (CSS Optimizer) от компании Яндекс. Но не обошлось и без ложки дегтя: дополнительный выигрыш в 0,57% при сжатии объединенного файла, был получен за счет удаления двух комментариев вида:
/*! какой-нибудь текст */
. Как правило, в таких комментариях содержится информация о версии библиотеки и ее разработчиках. CSSO оставляет лишь первый такой комментарий, а остальные удаляет (см. UPD2).Microsoft Ajax CSS Minifier снова показал хороший результат по сравнению своим основным конкурентом — YUI CSS Compressor for .Net.
Больше всего меня удивил новичок — Clean-css от компании Goal Smashers!. От столь популярного в Node.js-сообществе CSS-минимизатора (Clean-css используется пакетом grunt-contrib-cssmin) я ожидал большей степени сжатия. По эффективности минимизации он расположился между встроенными минимизаторами препроцессоров LESS и Sass.
Новая версия структурного минимизатора от компании Microsoft — WebGrease Semantic CSS Minifier до сих пор содержит в себе критические ошибки:
- Не может обрабатывать директиву
@charset
и правило@-o-keyframes
. - Обнуляет дробные значения, которые меньше единицы.
Поэтому WebGrease Semantic CSS Minifier опять выбывает из борьбы.
Из графика практически не видно, что файлы, полученные путем минимизации файла с объединенным кодом (исключение составляет файл, обработанный с помощью CSSO), по размеру немного меньше файлов, собранных из отдельно минимизированных файлов. Меньший размер таких файлов объясняется двумя причинами:
- Были удалены лишние переводы строк, разделяющие код отдельных файлов.
- Несколько директив
@charset
были объединены в одну.
Поэтому можно сделать вывод: что минимизация файла с объединенным кодом практически не дает выигрыша в размере файла.
Сравнение минимизаторов JS-кода
Сравним следующие алгоритмы минимизации JS-кода:
Таблица 4. Информация об адаптерах и алгоритмах минимизации JS-кода
Адаптер | Алгоритм минимизации | Сайт исходной библиотеки |
---|---|---|
CrockfordJsMinifier |
JSMin от 29.03.2013 | http://github.com/douglascrockford/JSMin |
YuiJsMinifier |
YUI JS Compressor for .Net 2.3.0.0 | http://yuicompressor.codeplex.com |
ClosureLocalJsMinifier |
Closure Compiler Application от 26.08.2013 (режим Simple ) |
http://developers.google.com/closure/compiler/docs/gettingstarted_app |
MicrosoftAjaxJsMinifier |
Microsoft Ajax JS Minifier 4.97 | http://ajaxmin.codeplex.com |
UglifyJsMinifier |
UglifyJS 2.4.0 | http://github.com/mishoo/UglifyJS2 |
Если вы уже заметили, то в приведенном выше списке отсутствует адаптер-минимизатор
EdwardsJsMinifier
. Поскольку поддерживаемый им алгоритм минимизации Packer 3.0 не менялся с 2007 года, то я решил не включать его в данный обзор.В качестве исходных файлов мы будем использовать:
bootstrap.js
из Twitter Bootstrap 3.0.0jquery-ui-1.10.3.custom.js
из jQuery UI 1.10.3MicrosoftAjax.debug.js
из Microsoft AJAX Framework 4.0.0.0knockout-2.3.0.debug.js
из Knockout 2.3.0jsrender.js
из JsRender 1.0.0-betalinq.js
из LINQ for JavaScript 2.2.0.2moment.js
из Moment.js 2.1.0
Размер объединенного файла составляет 1218,9 КБ, а после применения GZip-сжатия — 406,3 КБ.
Таблица 5. Результат применения алгоритмов JS-минимизации к каждому файлу по отдельности
Адаптер | Размер после минимизации, КБ | Экономия | Размер после минимизации с GZip-сжатием, КБ | Экономия при GZip-сжатии | ||
---|---|---|---|---|---|---|
в КБ | в % | в КБ | в % | |||
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 |
Таблица 6. Результат применения алгоритмов JS-минимизации к объединенному файлу
Адаптер | Размер после минимизации, КБ | Экономия | Размер после минимизации с GZip-сжатием, КБ | Экономия при GZip-сжатии | ||
---|---|---|---|---|---|---|
в КБ | в % | в КБ | в % | |||
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 |
![Диаграмма эффективности алгоритмов JS-минимизации](https://habrastorage.org/getpro/habr/post_images/252/212/5fa/2522125fab9147210b715bb39ad0190a.png)
Рис. 2. Экономия за счет использования алгоритмов JS-минимизации (в процентах)
Из приведенных выше данных видно, что минимизатор Closure Compiler от компании Google по-прежнему на первом месте.
Microsoft Ajax JS Minifier на этот раз обогнал UglifyJS и по праву занял второе место.
Вообще, UglifyJS меня очень сильно удивил тем, что при минимизации файла с объединенным кодом размер результирующего файла не только не уменьшился, а наоборот увеличился. Что говорит о некоторых недоработках в алгоритме.
YUI JS Compressor for .Net сильно отстал от первой тройки минимизаторов, что свидетельствует об устаревании его алгоритма.
Несмотря на то, что JSMin до сих развивается, принципы, заложенные в нем, остались прежними: никакого вмешательства в логику скрипта, только удаление комментариев и пробельных символов. Поэтому в данном обзоре JSMin является даже не участником, а выполняет роль нижней границы.
Также как и в случае с CSS-минимизаторами мы получили совсем незначительный выигрыш от минимизации файла с объединенным кодом.
Заключение
Как и в прошлый раз, битву минимизаторов выиграли поисковые гиганты — Яндекс и Google. Приятно сознавать, что лучший CSS-минимизатор был создан в российской компании.
Несмотря на серьезные проблемы с минимизатором WebGrease Semantic CSS Minifier, компания Microsoft добилась серьезных успехов при разработке семейства минимизаторов Microsoft Ajax Minifier.
Все исходные и минимизированные файлы доступны по адресу — https://www.dropbox.com/s/k232cloh87sn9pr/css-and-js-minifiers-sep-2013-files.zip.
UPD1: Переделал графики на отображение процентов.
UPD2: По поводу «ложки дегтя» в CSSO был получен комментарий от Сергея Крыжановского (разработчика CSSO). На самом деле это не недоработка, а просто особенность структурной минимизации: при изменении структуры таблицы стилей такие комментарии могут отделиться от кода, к которому они относятся, и просто «повиснуть» в таблице стилей. Поэтому и сохраняется только первый комментарий. Здесь ситуация похожа на аналогичную ситуацию с Closure Compiler, который при структурной минимизации JS-кода удаляет вообще все комментарии.
UPD3: Попробовал провести тесты с CSS-минимизатором Closure Stylesheets. Сначала протестировал последнюю доступную версию бинарника — closure-stylesheets-20111230.jar и получил ошибку при минимизации файла
bootstrap.css
. Потом собрал из исходников самую последнюю версию (коммит 86bb800d79a3) и опять получил ошибку при минимизации файла bootstrap.css
: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
Кроме того, попытался также минимизировать
jquery-ui-1.10.3.custom.css
и animate.css
, и снова получил ошибки.Поэтому Closure Stylesheets, также как и WebGrease Semantic CSS Minifier, не может участвовать сравнительных тестах данного обзора.
UPD4: Добавил ссылку на архив с исходными и минимизированными файлами — https://www.dropbox.com/s/k232cloh87sn9pr/css-and-js-minifiers-sep-2013-files.zip.
Опрос
В заключении статьи предлагаю вам принять участие в опросе. Если вы не нашли ваш минимизатор в списке вариантов ответа, то выберите вариант `Другой`, а затем укажите в комментариях его название и адрес сайта разработчиков.
Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.
Какой алгоритм минимизации CSS-кода вы используете в своих проектах?
5.2% Clean-css17
3.98% CSS::Minifier13
3.06% CssMin Джо Сцилла10
15.6% CSSO (CSS Optimizer)51
2.14% CSSTidy7
0% Efficient stylesheet minifier Мэдса Кристенсена0
5.5% Microsoft Ajax CSS Minifier18
1.83% WebGrease Semantic CSS Minifier6
21.71% YUI CSS Compressor71
19.88% Средства минимизации LESS65
12.23% Средства минимизации Sass40
8.87% Другой29
Проголосовали 327 пользователей. Воздержались 267 пользователей.
Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.
Какой алгоритм минимизации JavaScript-кода вы используете в своих проектах?
25.28% Closure Compiler91
0% Dojo ShrinkSafe0
1.39% JavaScript::Minifier5
7.78% JSMin28
6.67% Microsoft Ajax JS Minifier24
2.22% Packer8
33.06% UglifyJS119
15% YUI JS Compressor54
8.61% Другой31
Проголосовали 360 пользователей. Воздержались 266 пользователей.