JavaScript: жать или не жать?

Давайте рассмотрим далее сжатие JavaScript-файлов и проведем анализ всех наиболее известных средств статической минимизации JavaScript-кода. Нам нужно, по сути, ответить на три основных вопроса:

  • Имеет ли смысл пользоваться каким-либо минимизатором JavaScript-кода?
  • Есть ли среди них универсальное средство, показывающее лучшие результаты в подавляющем большинстве случаев?
  • Если такого средства нет, то каковы критерии использования набора инструментов?

Итак, с постановкой задачи разобрались. Теперь перейдем, собственно, к самим инструментам и графикам степени сжатия исходного кода при их применении.

Инструменты и методика

Всего удалось обнаружить 5 кардинально различных средств для минимизации JavaScript- файлов, которые могут работать как автономные приложения (в расчете на то, что их можно будет далее запускать по событию или по расписанию, ориентируясь, в общем, на автоматизацию процесса публикации файлов на production-сервере).

1. JSMin ( http://www.crockford.com/javascript/jsmin.html ). Наиболее широко распространенный минимизатор, основывается на простых правилах, перенесен на множество языков, в том числе, и на сам JavaScript.

2. JavaScript::Minifier ( http://search.cpan.org/~pmichaux/JavaScript-Minifier- 1.04/lib/JavaScript/Minifier.pm ). Отдельный перловый модуль, по степени сжатия очень близок к JSMin, однако генерирует отличный от первого синтаксис.

3. Dojo ShrinkSafe aka Rhino ( http://dojotoolkit.org/docs/shrinksafe ). Первоначально разрабатывался как Rhino, затем был включен в состав Dojo. Запускается как jar- модуль.

4. Dean Edwards Packer ( http://dean.edwards.name/packer/ ). Достаточно широко известный инструмент от не менее известного Dean Edwards. Перенесен на некоторые языки, в том числе, на PHP4/5.

5. YUI Compressor ( http://developer.yahoo.com/yui/compressor/ ). В представлении также не нуждается, именно на его основе проведена оптимизация сайтов Yahoo. Для анализа использовалась версия 2.2.5. Запускается как jar-модуль.

Для анализа были найдены несколько достаточно больших и широко используемых JavaScript-файлов (вполне возможно, что вы их загружали в этом месяце или даже используете из кэша каждый день) разных размеров и степеней изначального сжатия.

Все исходные файлы сжимались всеми представленными инструментами, затем архивировались. Далее все полученные данные нужно было выстроить в какой-то последовательности, которая бы выявляла характер и преимущества сжатия файлов сторонними средствами. Критерием для такой последовательности была выбрана изначальная «сжимаемость» файлов (то, насколько они хорошо архивируются).

Вполне очевидно, что если файл уже достаточно плохо архивируется, то предварительное его сжатие каким-либо минимизатором ситуацию улучшить не должно (такие файлы обычно оформлены в довольно минималистичном стиле, и из них уже удалены все комментарии). Что и подтвердилось на конкретных примерах.

Графические результаты

Сами графики, собственно. Что на них изображено? Выведен выигрыш (в процентах) относительно несжатого файла (по оси ординат отложены проценты). По оси абсцисс отложены размеры исходных файлов. Внимание: файлы не расположены по размеру. Данные упорядочены по общей степени сжатия.

Все инструменты приведены на одном графике. Заметен явный выигрыш Packer без архивирования.

SpeedUpYourWebsite.v1.2_img_12

Рис. 12. Эффективность различных инструментов для минимизации JavaScript-файлов вместе по сравнению с gzip

При архивировании, однако, все минимизаторы кода ведут себя примерно одинаково.

SpeedUpYourWebsite.v1.2_img_13

Рис. 13. Эффективность различных инструментов для минимизации JavaScript-файлов вместе с дополнительным архивированием по сравнению с gzip

Для уточнения картины при архивировании минимизированного файла давайте отдельно выделим их преимущество (если оно имеется) относительно обычного архивирования.

SpeedUpYourWebsite.v1.2_img_14

Рис. 14. Эффективность различных инструментов для минимизации JavaScript-файлов вместе с дополнительным архивированием, увеличенный масштаб

Тут уже хорошо видно, что YUI Compressor ведет себя, в целом, лучше остальных скриптов.

Промежуточные выводы

Во-первых, стоит указать на практически идентичное поведение JSMin и JavaScript::Minifier — скорее всего, они действуют по достаточно похожему алгоритму. Однако последний обладает скрытым потенциалом (при более подробном рассмотрении файлов, полученных вследствие работы второго, оказалось, что они могут быть уменьшены еще), но он работает в несколько раз дольше аналогов (3-5 секунд против 0,3- 0,5 для Packer на PHP).

Во-вторых, файлы, которые меньше 1 Кб или при архивировании дают выигрыш меньше 70%, минимизировать не имеет смысла. Минимизация дает в таком случае результат, сравнимый с нулем. Если с сервера отдаются небольшие (до 20 Кб в несжатом виде) архивированные файлы (.gz), то стоит по умолчанию их минимизировать с помощью JSMin.

В-третьих, если на сервере не поддерживается сжатие скриптов, то отдавать лучше версию, минимизированную с помощью Packer, — в таком случае выигрыш довольно значительный (естественно, если размер файла больше 1 Кб). Такая минимизация, в среднем, показала 50% преимущество относительно несжатого файла.

В-четвертых, во всех остальных случаях (сервер отдает достаточно большие gzip-версии файлов, которые хорошо архивируются) стоит использовать YUI Compressor (в среднем, показал 6% преимущество относительно простого gzip).

Есть ли жизнь после сжатия?

Хочется отметить, что при минимизации JavaScript-файлов нужно следить за тем, чтобы функционал не уменьшился вследствие этой самой минимизации. Для проверки JS-файлов на работоспособность и общую адекватность существует проект JSLint ( http://jslint.com/ ), который сравнивает исходный файл с набором спецификаций по синтаксису и выдает сообщения об обнаруженных ошибках.

Скорость загрузки JavaScript-библиотек

В начале 2008 года командой PDWiki был проведен весьма впечатляющий анализ производительности JavaScript. Они собирались разобраться, насколько быстро грузятся JavaScript-библиотеки (естественно, скорость их загрузки будет заметно влиять на скорость загрузки всей страницы).

В результате было развернуто тестовое окружение для получения информации от различных браузеров, затем собрали все результаты в итоговом отчете. В нем достаточно много информации, которая может быть полезна как разработчикам веб-приложений, так и разработчикам браузеров: структурированные таким образом данные достаточно обширны и достойны быть объектом отдельного исследования.

Методы упаковки JavaScript

При загрузке JavaScript-кода обычно предполагается, что чем меньше загружаемый файл, тем быстрее он загрузится. Это несколько не соответствует действительности, что прекрасно подтверждает дальнейшее изучение ситуации. Мы рассмотрим скорость загрузки библиотеки jQuery в трех формах: обычной, уменьшенной (при помощи YUI Compressor) и упакованной (используется Packer). Если упорядочить их по размерам, то будет примерно так: самый маленький вариант, естественно, упакованный, затем уменьшенный, затем нормальный.

Однако упакованная версия добавляет некоторые накладные расходы: ее нужно сначала распаковать (выполнять достаточно тяжелый eval и replace) с помощью того же JavaScript на стороне клиента. Эта распаковка может занять достаточно продолжительное время при загрузке страницы. То есть, использование уменьшенной версии, в конце концов, будет значительно быстрее, чем упакованной — даже при достаточно большом размере файла. Ниже приводится сравнение времени загрузки различных вариантов уменьшения jQuery.

Вариант  Среднее время

Уменьшенный    519.7214

Упакованный     591.6636

Нормальный      645.4818

Таблица 1. Время загрузки библиотеки jQuery, которая была подвергнута различным уменьшениям

Очевидно, что при использовании любой техники сжатия стоит помнить о такой формуле:

Время_загрузки = Время_на_скачивание + Время_на_исполнение

Именно поэтому упакованный вариант, будучи наименьшим по размеру, может проигрывать в производительности другим, менее экстремальным, способам представления информации.

Подводя итог всем вышеприведенным выкладкам, можно сделать следующее заключение. Если использовать gzip-сжатие для текстовых файлов, то наилучшим выбором будет применение YUI Compressor для дополнительной минимизации CSS- и JavaScript-файлов. Результирующий файл будет, в среднем, самым маленьким из возможных вариантов сжатия и будет загружаться в браузере максимально быстро.

Производительность загрузки JavaScript-библиотек

Из этого исследования можно еще получить данные по влиянию производительности различных JavaScript-библиотек на загрузку страницы. Таким образом, более простая и меньшая по размеру библиотека будет загружаться быстрее аналогов. По результатам видно, что jQuery загружается достаточно быстро относительно других библиотек (200- 400 мс — существенный выигрыш в скорости). Ниже приведено среднее время загрузки неархивированных и не уменьшенных версий библиотек не из кэша.

Инструментарий   Среднее время

jquery-1.2.1           732.1935

dojo-1.0.1              911.3255

prototype-1.6.0       923.7074

yahoo-utilities-2.4.0  927.4604

protoculous-1.0.2     1136.5497

Таблица 2. Время загрузки различных библиотек (не модифицированные версии, без учета кэширования)

Сейчас, конечно,, можно возразить, что нечестно тестировать загрузку только не кэшированных страниц, ибо, согласно исследованиям Yahoo по кэшированию, примерно 50% посетителей не будут иметь возможности кэшировать содержание страницы. Поэтому важно убедиться, что не только первоначальная, но и кэшированная версия страницы также загружается максимально быстро. Итак, ниже приведены цифры для загрузки архивированных и уменьшенных версий из кэша.

Инструментарий   Среднее время

yahoo-utilities-2.4.0    122.7867

Jquery-1.2.1              131.1841

prototype-1.6.0         142.7332

dojo-1.0.1                171.2600

protoculous-1.0.2      276.1929

Таблица 3. Время загрузки различных библиотек (модифицированные версии, с учетом кэширования)

Если принять во внимание кэшированную версию, то разница становится уже не столь очевидна (всего 10-30мс — за исключением Dojo/Scriptaculous). Более того, при загрузке из кэша все издержки приходятся на инициализацию библиотек, — именно поэтому так важно знать и использовать принципы создания быстрых JavaScript-приложений. Об этом подробнее рассказывается в седьмой главе. Но давайте на этом закончим со сжатием текстовых файлов и перейдем к более интересным случаям — уменьшению в размере различных форматов изображений.

Posted in Разгони свой сайт.