A- A+

Сжатие css и js без потери производительности сервера

Современная вёрстка без таблиц, отказ от использования инлайновых стилей и сжатие html-страниц позволяют достаточно серьёзно уменьшить трафик сервера и повысить скорость загрузки сайта для пользователей, работающих на «узких» каналах. Выигрыш в трафике может составлять 60-80% (для HTML)!

Несмотря на это, всё равно остаётся ряд достаточно больших файлов, которые браузер посетителя должен будет загрузить: основной css с вёрсткой (от 10 до 30КБ), javascript-фреймворк (mootools - 70-80КБ, prototype.js - 120КБ и т.д.) Конечно, эти файлы кешируются браузером и грузятся только при первом посещении, но не мне вам объяснять, насколько важно, чтобы после перехода из выдачи поисковика пользователь увидел загруженный сайт как можно быстрее…

Сжимать эти файлы можно при каждом обращении, прогоняя через mod_gzip (mod_deflate). Но это неизбежно приведёт к дополнительной нагрузке на сервер, которая может оказаться критической для посещаемого сайта на недорогом виртуальном хостинге.

Другой способ, который и будет рассмотрен в данной статье, — хранить сжатые (.gz) файлы на сервере наряду с исходными и с помощью директив mod_rewrite выдавать .js.gz и .css.gz вместо .js и .css соответственно. Итак, приступим.

Сначала нужно определиться, какие файлы требуют сжатия. Для типичного шаблона Joomla!, например, это будут, как правило, /media/system/js/mootools.js и template_css.css активного шаблона.

Теперь нужно подготовить сжатые версии файлов. Это можно сделать в Windows с помощью бесплатного архиватора 7-ZIP, выбрав GZip в качестве формата при создании архива. Обратите внимание: каждый файл в отдельном архиве. В консоли UNIX-сервера это можно сделать с помощью команды gzip:

 
gzip mootools.js -c > mootools.js.gz
 

После этого требуется разместить .js.gz и .css.gz в тех же директориях на сервере, где расположены их несжатые версии (если сжатие делалось в Windows с помощью 7-Zip).

Если .htaccess в корне сайта не существует, создаём его и добавляем следующие строки:

Вариант 1

 
### Ассоциируем расширение .gz с gzip
AddEncoding gzip .gz
 
### Задействуем mod_rewrite
RewriteEngine On
 
### Отдаём foo.bar.gz вместо файла foo.bar, если foo.bar.gz присутствует в той же директории,
### что и foo.bar. Если браузер - Safari, отдаём foo.bar
RewriteCond %{HTTP:Accept-encoding} gzip
RewriteCond %{HTTP_USER_AGENT} !Safari
RewriteCond %{REQUEST_FILENAME}.gz -f
RewriteRule ^(.*)$ $1.gz [QSA,L]
 

Вариант 2

Однако это способ иногда не работает. Сервер устанавливает HTTP-заголовок Content-Type в application/x-gzip и браузеры, определяющие тип данных по нему (например, Firefox), а не по содержимому (IE) «не видят» скрипты и css. Чтобы решить эту проблему, нужно принудительно устанавливать Content-Type в text/javascript или text/css. В этом случае надо добавить в .htaccess такой код («вариант 1» надо убрать или закомментировать!):

 
AddEncoding gzip .gz
 
### 1. Обработка js-файлов
<FilesMatch "\.js.gz$">
  ForceType text/javascript  
  Header set Content-Encoding: gzip
</FilesMatch>
<FilesMatch "\.js$">
  RewriteEngine On
  RewriteCond %{HTTP_USER_AGENT} !".*Safari.*"
  RewriteCond %{HTTP:Accept-Encoding} gzip
  RewriteCond %{REQUEST_FILENAME}.gz -f
  RewriteRule (.*)\.js$ $1\.js.gz [L]
  ForceType text/javascript
</FilesMatch>
 
### 2. Обработка css-файлов
<FilesMatch "\.css.gz$">
  ForceType text/css
  Header set Content-Encoding: gzip
</FilesMatch>
<FilesMatch "\.css$">
  RewriteEngine On
  RewriteCond %{HTTP_USER_AGENT} !".*Safari.*"
  RewriteCond %{HTTP:Accept-Encoding} gzip
  RewriteCond %{REQUEST_FILENAME}.gz -f
  RewriteRule (.*)\.css$ $1\.css.gz [L]
  ForceType text/css
</FilesMatch>
 

Всё, никаких изменений больше не нужно!

Проверить корректность работы метода можно в Firefox с установленным плагином Live HTTP Headers:

  1. Очистите кеш
  2. Откройте окошко плагина, очистите лог, убедитесь, что стоит галочка напротив Capture
  3. Не закрывая окна Live HTTP Headers, перезагрузите сайт
  4. В ответах сервера на GET-запросы для сжатых файлов должно быть примерно следующее:

    Запрос браузера

    http://vectora.ru/templates/vectora/css/template.css
    
    GET /templates/vectora/css/template.css HTTP/1.1
    Host: vectora.ru
    User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.14) Gecko/20080404 Firefox/2.0.0.14
    Accept: text/css,*/*;q=0.1
    Accept-Language: en-us,en;q=0.5
    Accept-Encoding: gzip,deflate
    Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
    Keep-Alive: 300
    Connection: keep-alive
    

    Ответ сервера

    HTTP/1.x 200 OK
    Server: nginx/0.5.35
    Date: Sat, 19 Apr 2008 18:01:45 GMT
    Content-Type: text/css
    Connection: keep-alive
    Keep-Alive: timeout=20
    Last-Modified: Tue, 01 Jan 2008 22:56:51 GMT
    Etag: "40bc5ff-131d-477ac533"
    Accept-Ranges: bytes
    Content-Length: 4893
    Content-Encoding: gzip
    
    

История изменений:

  • 19.04.2008 — первичная публикация;
  • 14.11.2008 — добавление альтернативного варианта (FilesMatch);
  • 21.03.2009 — исправлена опечатка в примере альтернативного варианта (FilesMatch).