Сжатие JavaScript и CSS

29.04.2009

Проблему отдачи 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 редакторов в панели управления.

Метки: