Сжатие JavaScript и CSS

Проблему отдачи JavaScript и CSS уже много раз обсуждали и есть множество готовых решений для этого. Я бы хотел рассказать как это делается в наших сайтах и почему я выбрал именно этот способ.

Что я пробовал для JavaScript:

1. Хранить minified версии нужных скриптов на сервере, а при отдаче клиенту склеивать их в один файл, затем сохранять его в кэше. При последующих обращениях склеенный файл просто отдается как статика с корректными заголовками и e-tagом от апача. Именем файла является md5 от всех имен подключенных скриптов. Недостатком является "немобильность" кэша. Единожды созданный он разрастается до больших размеров при изменении исходных файлов и по сути на каждую версию скриптов создается по файлу - плохо для разработки. Также отсутствует контроль заголовков скрипом сайта.

2. При загрузке страницы делать запрос на JavaScript, в котором закодированы имена всех нужных файлов. Сервер отдает JavaScript динамически с проставлением нужных заголовков. Недостаток - нечитаемый и длинный URL для JavaScript, ограничение на длину запроса (т. е. нельзя подключить много скриптов).

3. Используемый сейчас метод. Сжатие вообще всех JavaScript сайта с помощью установки хэндлера апач.

Action mh "/x_gs/"
AddHandler mh .css .js

То есть любой скрипт будет обработан php скриптом по адресу /x_gs/. Там происходит сжатие скрипта с помощью yuicompressor и его отдача. При этом контролируются все заголовки: Expires устанавливается на месяц вперед, Last-modified равен дате изменения файла скрипта, e-tag - md5 от имени файла + дата модификации Все это обжимается gzip. При повторном запросе проверяется e-tag и last-modified. Это позволяет при последующих обращениях отдавать только 304 ответ. У этого подхода есть недостаток - при большом количестве посещений можно нагрузить сервер сжатием yuicompressor. Например jquery 1.3.2 в среднем жмется около 500 мс - очень долго. Для обхода этой проблемы сжатый скрипт кэшируется в memcached с ключем - именем файла + дата модификации, что позволяет использовать такое кэширование на всем сервере сразу, а не в рамках отдельного сайта. Если на хостинге нет java - используется JSMin.

Что я пробовал для CSS:

Практически то же самое, за исключением той особенности CSS, что нельзя просто склеить все цсски в 1 файл, если они из разных каталогов, так как background картинки в них прописываются относительно положения файлов. Сейчас CSS отдается так же как и JavaScript. Сжимается тем же yuicompressor. Если нет java - CSSTidy.

Результат очень неплох. Размер скриптов минимален. Разработку вести удобно, так как нет кэшей, которые бы не зависили от времени изменения файла. Никаких каталогов к эшами. Нагрузка на сервер упала, так как в большинстве случаев видим 304 ответ. Особенно приятно видеть, что сжимается не только то что я использую на самом сайте, но и скрипты MCE/FCK редакторов в панели управления.


Самое интересное