Сжатие Javascript и CSS

При сжатии javascript, как и HTML/CSS, используется GZIP на сервере: mod_deflate в apache/nginx, mod_deflate/mod_compress в lighttpd.

Это - универсальное сжатие. Но есть и специфическое, которое помогает уменьшить размер в 2 и более раза, по сравнению с простым gzip.

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

YUI Compressor

Рекомендация номер один. YUI Compressor(страница)
использует парсер javascript, написанный на языке java, который называется Rhino.

Патченный Rhino сжимает за счет двух основных операций:

  1. убирает лишние пробельные символы и комментарии
  2. заменяет имена локальных переменных на более короткие

Софт

Чтобы его использовать, нужны такие компоненты:

Запуск

Сжать файл myfile.js в myfile-min.js:

java -jar yuicompressor-x.y.z.jar myfile.js -o myfile-min.js

Также есть ряд полезных опций, о которых Вы узнаете, запустив:

java -jar yuicompressor-x.y.z.jar -h

Компрессор также умеет сжимать CSS, вставлять переносы строк после каждой точки с запятой, или каждые NN символов, и т.д.

Если русские символы криво сжимаются --- используйте опцию "charset".

Важно: при сжатии, в целях безопасности, YUICompressor не будет сжимать локальные переменные во всех областях видимости, связанных с вызовами with и eval. Поэтому использовать эти конструкции не рекомендуется.

Packer

Можно использовать для обфускации javascript, для сжатия не рекомендуется.

Утилита Packer доступна на нескольких языках программирования по адресу http://dean.edwards.name/download/#packer.

Можно поиграть с реализацией packer на javascript по адресу http://dean.edwards.name/packer/.

Пример и принцип работы

Packer делает следующее:

  1. Сжимает javascript регулярными выражениями
  2. Использует алгоритм архивации со словарем

Например, напустим PHP-версию на скрипт:

function somefunc() {
	var test = 5
	var myTest = 7

	/* go go go!!! */
	go(myTest)
}

Результат сжатия (все в одну строку):

eval(function(p,a,c,k,e,d){e=function(c){return c};if(!''.replace(/^/,String)){while(c--){d[c]=k[c]||c}k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--){if(k[c]){p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c])}}return p}('3 6(){1 2=5 1 0=7 4(0)}',8,8,'myTest|var|test|function|go||somefunc|'.split('|'),0,{}))

При загрузке javascript разжатие осуществляется автоматически запуском eval.

Это означает, что нагрузка по разархивации ложится на javascript.
Есть мнения (new.com: http://www.clientcide.com/best-practices/optimization/dean-edwards-packer-compression-tool/ ), что это может привести к неоправданным тормозам на разархивацию вместо загрузки.

Тем более, что JS-файл кешируется, и при последующих заходах на страницу браузер будет снова и снова разархивировать один и тот же javascript-файл.

Резюме по Packer

Packer имеет смысл использовать для сжатия javascript в двух случаях:

  1. Вы не хотите использовать gzip-компрессию, например, чтобы избежать глюков старых браузеров при распаковке javascript
  2. Вы хотите обфусцировать код, сделать его непонятным

В остальных случаях можно обойтись YUI Compressor как для Javascript так и для CSS.

Update: статистика по сжатию jQuery.js

Версия jQuery: 1.3.2. Это для примера, с тем же успехом можно было взять и другую ветку.

В названии файлов

Несколько суффиксов обозначают два последовательно запущенных компрессии. Например, .min + .gz означает минифицированный и затем gzip'ованный скрипт.

Почти все современные браузеры принимают от сервера gzip'ованные скрипты.

jquery-1.3.2.js 120763
jquery-1.3.2.js.gz 35361
jquery-1.3.2.min.js 57254
jquery-1.3.2.min.js.gz 19716
jquery-1.3.2.pack.js 41025
jquery-1.3.2.pack.js.gz 20274

Из таблицы видно, что наилучший результат достигается после минификации с последующим gzip (jquery-1.3.2.min.js.gz).

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

UPDATE: Google Closure Compiler

На текущий момент наилучшим способом сжать javascript является использование Google Closure Compiler.

Этот инструмент заслужил отдельный цикл статей: Google Closure Compiler в деталях.

Соответственно, рекомендация: Google Closure Compiler + GZIP. Причины те же.