<FilesMatch .*\.(html|phtml|php|shtml)$>
Header append Cache-Control private
</FilesMatch>
Полные оптимизированные конфигурации для указанных серверов приведены в восьмой главе.
2.2. CSS и JavaScript в виде архивов
проверить, умеет ли клиент принимать файлы в формате gzip-encoded;
обеспечить соответствующий вывод на стороне сервера через gzip-функции либо организовать это непосредственно через веб-сервер (например, Apache);
настроить конфигурационные файлы (или .htaccess), чтобы обеспечить корректный Content-Type.
В данном случае сжатие данных «на лету», возможно, не будет наиболее оптимальным решением, потому что файлы стилей и скриптов изменяются достаточно редко, а мы заставим сервер каждый раз их сжимать. Тем более что лучше самого сервера с архивацией файлов никто не справится.
Статическое архивирование в действии
Предположим, что у нас есть JavaScript-библиотека jquery.js на сервере. Заархивируем ее в jquery.js.gz (при помощи 7-zip или любой другой утилиты, если в работе используется Windows). В итоге, должен появиться файл jquery.js.gz. Его нужно положить в ту же директорию на сервере, что и исходный файл.
Если работать прямо на сервере через командную строку, то достаточно выполнить следующую команду:
gzip jquery.js -c n -9 > jquery.js.gz
Опция c создаст новый файл (перенаправляем поток вывода в jquery.js.gz), -n исключит имя файла из архива (оно там только лишние байты занимает), а -9 заставит использовать максимальную степень сжатия. Таким образом, мы получим минимально возможный архив из искомого файла.
Проблемы для Safari
Нам нужно именовать все архивы стандартным образом, но при этом иметь неархивированную версию для обратной совместимости (например, с дополнительным суффиксом nogzip). Поэтому для подготовки файлов нам будут нужны две команды (jquery здесь используется только в качестве примера):
cp $src/jquery.js $dst/jquery.nogzip.js
gzip $dst/jquery.nogzip.js -9 n -c > $dst/jquery.js
где $src директория, в которой хранятся исходные файлы, а $dst финальная директория для публикации. Сначала мы копируем файл в финальное место дислокации, а потом его архивируем под «правильным» именем.
Конфигурируем Apache
<IfModule mod_rewrite.c>
RewriteEngine On
# перенаправляем Konqueror и «старые браузеры»
RewriteCond %{HTTP:Accept-encoding} !gzip [OR]
RewriteCond %{HTTP_USER_AGENT} Konqueror
RewriteRule ^(.*)\.(css|js)$ $1.nogzip.$2 [QSA,L]
</IfModule>
Вся вышеуказанная конструкция «обернута» условием наличия на сервере подключенного mod_rewrite. Если он отсутствует, то это сразу станет видно на заявленных браузерах (перестанут отображаться стили и отрабатывать скрипты). Иначе Apache просто не сможет запуститься, т. к. RewriteEngine не будет объявлен.
Дополнительно к заявленной логике необходимо выставить ряд заголовков для отдаваемых файлов. В частности, Vary и Cache-control касаются локальных проксирующих серверов, которые не должны кэшировать эти файлы, а пропускать их дальше к пользователю, не обрезая при этом заголовок User-Agent (иначе наш сервер никак не узнает, можно ли отдавать архивированную копию файла или нет).
<IfModule mod_headers.c>
Header append Vary User-Agent
# выставляем для всех css/js файлов Content-Encoding
<FilesMatch .*\.(js|css)$>
Header set Content-Encoding: gzip
Header set Cache-control: private
</FilesMatch>
# сбрасываем Content-Encoding в том случае, если отдаем не архив
<FilesMatch .*\.nogzip\.(js|css)$>
Header unset Content-Encoding
</FilesMatch>
</IfModule>
В итоге для всех файлов, которые мы отдаем как архивы, дополнительно объявляется Content-Encoding, а для их неархивированных копий этот заголовок сбрасывается. Чем и достигается полная работоспособность данного решения.
Маленькие «но»
Итак, финальный алгоритм действий (при наличии на сервере mod_headers; иначе лучше воспользоваться конфигурацией, приведенной в восьмой главе) должен быть следующим:
Добавляем описанные выше инструкции (оба блока) в конфигурационный файл Apache или.htaccess
Пакуем
файлы (с помощью 7-zip или gzip) и кладем на место обычных (расширение у файлов должно остаться прежним, .css или .js). Например, если у нас есть файл anyname.css, то после упаковки получается файл anyname.css.gz; переименовываем его обратно в anyname.css и заливаем на сервер. Для gzip все немного проще:
gzip -c -9 -n anyname.css > anyname.css.gz
mv anyname.css anyname.nogzip.css
mv anyname.css.gz anyname.css
Рядом с сжатыми файлами кладутся файлы с расширением nogzip.css или nogzip.js, которые содержат неархивированные копии. Например, после заливки сжатого файла anyname.css нужно создать на сервере еще один файл anyname.nogzip.css, который является копией несжатого файла. Для gzip это копирование уже производится чуть выше второй строкой в листинге.
Два слова о nginx
Однако, на данный момент таких случаев доли процента, поэтому если у нас проект с низкой или средней посещаемостью, указанный модуль (в совокупности с ngx_http_gzip_module) позволит преодолеть почти все «подводные камни». Подробная конфигурация для nginx и Apache приведена в восьмой главе.