Pull to refresh

Сравнение эффективности минимизаторов CSS- и JavaScript-кода (Сентябрь 2013)

Reading time 8 min
Views 23K
Логотипы модулей-минимизаторов из Bundle Transformer

За прошедшие, с момента публикации предыдущего обзора, 3 месяца уже успели обновиться почти все рассмотренные алгоритмы минимизации (кроме, Packer`а). Кроме того в Bundle Transformer появился новый модуль-минимизатор на базе Clean-css — BundleTransformer.CleanCss.

При подготовке данного сравнительного обзора были учтены следующие пожелания читателей:
  1. В предыдущем обзоре в качестве исходных файлов использовались: bootstrap.css и bootstrap.js из Twitter Bootstrap 2.3.2, из-за чего достоверность результатов была низкой. В новом же обзоре размер выборки был увеличен: для сравнения были отобраны 7 JS-файлов и 5 CSS-файлов из 10 популярных Open Source-проектов.
  2. Теперь в сравнении минимизаторов CSS-кода также участвуют встроенные средства минимизации препроцессоров LESS и Sass.
  3. Как известно, 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.

В качестве исходных файлов мы будем использовать:
  1. bootstrap.css из Twitter Bootstrap 3.0.0
  2. jquery-ui-1.10.3.custom.css из jQuery UI 1.10.3
  3. animate.css из Animate.css от 15.08.2013
  4. hint.css из Hint.css 1.3.0
  5. zocial.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-минимизации

Рис. 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 до сих пор содержит в себе критические ошибки:
  1. Не может обрабатывать директиву @charset и правило @-o-keyframes.
  2. Обнуляет дробные значения, которые меньше единицы.

Поэтому WebGrease Semantic CSS Minifier опять выбывает из борьбы.

Из графика практически не видно, что файлы, полученные путем минимизации файла с объединенным кодом (исключение составляет файл, обработанный с помощью CSSO), по размеру немного меньше файлов, собранных из отдельно минимизированных файлов. Меньший размер таких файлов объясняется двумя причинами:
  1. Были удалены лишние переводы строк, разделяющие код отдельных файлов.
  2. Несколько директив @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 года, то я решил не включать его в данный обзор.

В качестве исходных файлов мы будем использовать:
  1. bootstrap.js из Twitter Bootstrap 3.0.0
  2. jquery-ui-1.10.3.custom.js из jQuery UI 1.10.3
  3. MicrosoftAjax.debug.js из Microsoft AJAX Framework 4.0.0.0
  4. knockout-2.3.0.debug.js из Knockout 2.3.0
  5. jsrender.js из JsRender 1.0.0-beta
  6. linq.js из LINQ for JavaScript 2.2.0.2
  7. moment.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-минимизации

Рис. 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.

Опрос


В заключении статьи предлагаю вам принять участие в опросе. Если вы не нашли ваш минимизатор в списке вариантов ответа, то выберите вариант `Другой`, а затем укажите в комментариях его название и адрес сайта разработчиков.
Only registered users can participate in poll. Log in, please.
Какой алгоритм минимизации CSS-кода вы используете в своих проектах?
5.2% Clean-css 17
3.98% CSS::Minifier 13
3.06% CssMin Джо Сцилла 10
15.6% CSSO (CSS Optimizer) 51
2.14% CSSTidy 7
0% Efficient stylesheet minifier Мэдса Кристенсена 0
5.5% Microsoft Ajax CSS Minifier 18
1.83% WebGrease Semantic CSS Minifier 6
21.71% YUI CSS Compressor 71
19.88% Средства минимизации LESS 65
12.23% Средства минимизации Sass 40
8.87% Другой 29
327 users voted. 267 users abstained.
Only registered users can participate in poll. Log in, please.
Какой алгоритм минимизации JavaScript-кода вы используете в своих проектах?
25.28% Closure Compiler 91
0% Dojo ShrinkSafe 0
1.39% JavaScript::Minifier 5
7.78% JSMin 28
6.67% Microsoft Ajax JS Minifier 24
2.22% Packer 8
33.06% UglifyJS 119
15% YUI JS Compressor 54
8.61% Другой 31
360 users voted. 266 users abstained.
Tags:
Hubs:
+34
Comments 28
Comments Comments 28

Articles