Опубликован: 16.02.2009 | Доступ: свободный | Студентов: 1429 / 138 | Оценка: 4.26 / 4.17 | Длительность: 16:10:00
ISBN: 978-5-9963-0024-2
Лекция 2:

Уменьшение размера

Выводы

Во-первых, gzip и так показывает хорошее сжатие (до 81%), поэтому в большинстве случаев можно пользоваться только им.

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

В-третьих, замечен локальный выброс при файле небольшого размера. Он связан с тем, что gzip изначально его плохо сжал (вероятно, из-за маленькой исходной библиотеки слов), поэтому все минимизаторы показали себя на высоте. Однако файлы такого размера (порядка 1 Кб) стоит либо объединять с другими файлами (ибо тратить время на дополнительный запрос на сервер из-за такой мелочи не очень рационально), либо включить в сам HTML-файл. Так что данный выброс не стоит считать серьезным основанием для того, чтобы действительно использовать какой-либо минимизатор только из-за выигрыша в 3-4% от размера исходного файла.

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

В общем, если мы не хотим дополнительно морочить себе голову, то можно просто архивировать CSS-файлы (в среднем выигрыш 79%) либо проводить простую "подчистку мусора" перед архивированием (в среднем выигрыш 82%). Если мы заботимся о количестве байтов, то стоит изучить действие CSS Tidy и Minifier (их прелесть заключается в алгоритме перегруппировки селекторов) и использовать их, либо разработать собственное приложение.

Практический пример

По сравнению с JavaScript, сжимать CSS относительно просто. В силу практически полного отсутствия строк, заключенных в кавычки (в основном пути и названия шрифтов), мы можем изничтожить проблемы обычными регулярными выражениями. Когда же мы действительно встречаемся со строкой в кавычках, то мы можем объединить множественные пробелы в один (так как мы не рассчитываем обнаружить их в количестве больше чем 1 в URL или названиях шрифтов). Простейший скрипт на Perl может обеспечить нам все необходимые преобразования:

#!/usr/bin/perl

my $data = '';
open F, $ARGV[0] or die "Не получается открыть исходный файл: $!";
$data .= $_ while <F>;
close F;

$data =~ s!\/\*(.*?)\*\/!!g; # удаляем комментарии
$data =~ s!\s+! !g;      # сжимаем пробелы
$data =~ s!\} !}\n!g;     # добавляем переводы строки
$data =~ s!\n$!!;       # удаляем последний перевод строки
о       $data =~ s! \{ ! {!g;     # удаляем лишние пробелы внутри скобок
$data =~ s!; \}!}!g;     # удаляем лишние пробелы и синтаксис внутри скобок

print $data;

Осталось прогнать все наши CSS-файлы через этот скрипт, чтобы сжать их, например так:

perl compress.pl site.source.css > site.compress.css

Путем простых текстовых преобразований можно уменьшить общий объем передаваемых данных почти на 50% (конечный выигрыш очень сильно зависит от стиля кодирования; обычно будет получен менее впечатляющий результат), что обеспечит более быструю работу сайта для конечных пользователей в том случае, если gzip применить не удается.

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 без архивирования.

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

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

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

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

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

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

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

Рис. 2.12. Эффективность различных инструментов для минимизации 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-библиотеки (естественно, скорость их загрузки будет заметно влиять на скорость загрузки всей страницы).

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