Сжатие ответов Веб-сервера Apache средствами модуля mod_deflate
Эта заметка продолжает статьи Краткое руководство по Google Page Speed и Оптимизация кеширования сайта браузерами и прокси-серверами, посвященные повышению производительности Веб-серверов и CMS размещенных на них сайтов. На этот раз я рассмотрю использование модуля mod_deflate, который входит в состав второго поколения Веб-сервера Apache и является эффективной заменой своего предшественника - модуля mod_gzip, предназначенного для Веб-сервера Apache 1.3.xx.
Чем обоснован выбор модуля mod_deflate?
Вполне закономерный вопрос, особенно c учетом существования многочисленных альтернатив, таких как специализированные библиотеки, плагины для популярных CMS и различные решения на базе модуля mod_rewrite. Если ответить максимально коротко, то использование различных PHP-средств (специализированных библиотек и плагинов) существенно повышает потребление системных ресурсов, а применение модуля mod_rewrite, отдающего сжатые объекты вместо запрошенных несжатых, на мой взгляд, неудобно. Модуль mod_deflate лишен этих недостатков, прост в настройке и обеспечивает одно из лучших соотношений быстродействия и качества сжатия, с одной стороны, и аппетитом к системным ресурсам Веб-сервера, с другой.
Результаты анализа сайта до активации модуля mod_deflate
В процессе анализа параметров данного сайта с помощью Google Page Speed я заметил, что тест Enable gzip compression завершается с не самым приятным результатом
, все каскадные таблицы стилей и скрипты на языке JavaScript отдаются Веб-сервером в несжатом виде, например:
В данном фрагменте списка Show Resources можно увидеть, что файл style.css, имеющий размер 5537 байт, передается в несжатом виде, т.к. значение заголовка Content-Length (размер передаваемого контента) и значения в столбцах File Size (размер файла) / Transfer Size (объем передаваемых данных) равны размеру файла, а также отсутствует заголовок Content-Encoding (способ кодирования контента). Для всех остальных каскадных таблиц стилей и скриптов на языке JavaScript наблюдалась аналогичная ситуация. Отмечу, что мне повезло со статическими HTML-страницами, которые сжимаются Веб-сервером nginx, используемым моим хостером в качестве HTTP-акселератора.
Активация и настройка модуля mod_deflate
Для того, чтобы Веб-сервер Apache сжимал все каскадные таблицы стилей и скрипты на языке JavaScript средствами модуля mod_deflate, необходимо добавить в файл .htaccess, который находится в корневой папке сайта, или в файл httpd.conf/vhost.conf (в зависимости от конфигурации используемого хостинга), следующие строки:
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE application/javascript
AddOutputFilterByType DEFLATE text/javascript
AddOutputFilterByType DEFLATE text/css
<IfModule mod_setenvif.c>
BrowserMatch ^Mozilla/4 gzip-only-text/html
BrowserMatch ^Mozilla/4\.0[678] no-gzip
BrowserMatch \bMSIE !no-gzip !gzip-only-text/html
</IfModule>
</IfModule>
Данный фрагмент файла конфигурации Веб-сервера Apache проверяет наличие модуля mod_deflate и, если модуль mod_deflate доступен, включает сжатие каскадных таблиц стилей и скриптов на языке JavaScript, а также проверяет наличие модуля mod_setenvif и, если модуль mod_setenvif доступен, изменяет параметры сжатия для некоторых браузеров, которые некорректно обрабатывают сжатые файлы. Если на хостинге отсутствует HTTP-акселератор, либо он не сжимает HTML-страницы, следует добавить еще одну директиву AddOutputFilterByType:
AddOutputFilterByType DEFLATE text/html
Некоторые руководства предлагают поступить иначе - включить сжатие всех объектов, исключив объекты, сжатие которых не имеет смысла (например, архивы, изображения и мультимедийные файлы). При таком подходе следует заменить строки 2-4 следующими строками:
SetOutputFilter DEFLATE <IfModule mod_setenvif.c> SetEnvIfNoCase Request_URI \.(?:rar|zip)$ no-gzip dont-vary SetEnvIfNoCase Request_URI \.(?:gif|jpg|png)$ no-gzip dont-vary SetEnvIfNoCase Request_URI \.(?:avi|mov|mp4)$ no-gzip dont-vary SetEnvIfNoCase Request_URI \.mp3$ no-gzip dont-vary </IfModule
Данный фрагмент файла конфигурации Веб-сервера Apache включает сжатие всех объектов, а при наличии модуля mod_setenvif запрещает сжатие архивов с расширениями .rar и .zip, изображений с расширениями .gif, .jpg и .png, видеофайлов с расширениями .avi, .mov и .mp4 и аудиофайлов с расширением .mp3. Я противник такого подхода, т.к. он может затронуть гораздо больше число объектов, чем требуется.
Следует отметить, что существуют и другие директивы, которые предназначены для более тонкой настройки модуля mod_deflate, однако, во-первых, их описание выходит за рамки данной заметки, а во-вторых, их можно использовать только в файлах httpd.conf/vhost.conf, а не в доступных на большей части хостингов файлах .htaccess (последний вариант вызовет ошибку 500 - Internal Server Error). Не стоит переживать по поводу тонкой настройки модуля mod_deflate, рассмотренных директив будет более чем достаточно для большинства сайтов.
Результаты анализа сайта после активации модуля mod_deflate
После активации модуля mod_deflate тест Enable gzip compression завершается с результатом
, все каскадные таблицы стилей и скрипты на языке JavaScript отдаются Веб-сервером сжатым, например, для упомянутого выше файла теперь можно увидеть такую информацию:
В данном фрагменте списка Show Resources видно такие изменения, как уменьшение значений Content-Length и Transfer Size более чем в три раза и появление заголовка Content-Encoding, сообщающего, что файл сжат методом gzip. Cитуация для всех остальных каскадных таблиц стилей и скриптов на языке JavaScript полностью аналогична - в зависимости от исходного размера они сжаты в два-четыре раза.
Заключение
Если на Вашем хостинге используется Веб-сервер Apache второго поколения (версий 2.0.xx или 2.2.xx), обязательно посмотрите в сторону использования модуля mod_deflate, т.к. он без каких-либо проблем позволяет более чем в три раза уменьшить объем трафика, генерируемого Вашим сайтом и, соответственно, во столько же раз увеличить скорость отображения Вашего сайта браузерами посетителей. На этом я делаю паузу в рассуждениях об оптимизации производительности Веб-серверов и поздравляю Вас с наступающими праздниками!




Хорошая статья, а главное полезная. Спасибо!
Спасибо за статью, все четко и понятно расписано!
На здоровье
А не подскажете, в чем отличие
!no-gzipиno-gzip. То есть в чем смысл восклицательного знака?Apache прекрасно документирован! Ответ на Ваш вопрос находится здесь
AddOutputFilterByType DEFLATE application/javascript
AddOutputFilterByType DEFLATE text/javascript
AddOutputFilterByType DEFLATE text/css
лучше заменить на:
AddOutputFilterByType DEFLATE text/css text/javascript application/x-javascript
Согласен, что так короче и удобнее.
[...] Сжатие ответов Веб-сервера Apache средствами модуля mod_defla… [...]
Добавил в свой
.htaccessтакой код:AddOutputFilterByType DEFLATE text/css text/javascript application/x-javascript
BrowserMatch ^Mozilla/4 gzip-only-text/html
BrowserMatch ^Mozilla/4\.0[678] no-gzip
BrowserMatch \bMSIE !no-gzip !gzip-only-text/html
Проверяю его работу с помощью плагина YSlow для Firefox, он показывает, что
*.cssжмутся, а*.jsне жмуться.Не подскажете, куда копать?
Гм, скушались строки из кода. В общем код как в статье.
Посмотрел в апаче файл
mime.typesТам есть строки:
application/javascript js
. . .
#text/javascript
Добавил в
.htaccessapplication/javascript– всё равно не заработало.Все зависит от настроек Apache. Задайте вопрос техподдержке своего хостинга.
У меня не хостинг, я арендую выделенный сервер, т.е. сам могу посмотреть или поменять настройки. Вопрос в том, куда смотреть.
Я не сталкивался с YSlow для Firefox. Воспользуйтесь Google Page Speed, чтобы узнать тип содержимого, который установлен на Вашем Веб-сервере для JS, а затем подкорректируйте
.htaccess.Google Page Speed показал
Content-Type: application/javascript, что я и внёс в.htaccess, но всё равно не жмётся.Попробуйте удалить код
... из.htaccessи добавить его вhttpd.conf, а затем перезапустить Apache.Попробую попозже, когда буду дома, но сомневаюсь, что поможет.
*.cssведь у меня жмёт, а не жмёт почему-то*.js.Чудес не бывает. Если у Вас нет специфически настроенного фронтенда на базе Apache или nginx, то остается искать несостыковки в конфигурации Apache.
Как я и предполагал, нечего не изменилось после переноса в
httpd.conf. Дальше*.cssжмётся,*.jsне жмётся. Я не говорил что это чудо, я только предполагал, что предлагаемое решение не решит проблему.Я предложил вариант, который позволяет обойти различные
AllowOverride(не знаю, как они выглядят в Вашем случае) и более предпочтителен для отладки. Пришлите адрес сайта мне в личку.А с чего это Вы взяли, что у Вас
*.jsне жмутся? Те, которые лежат на Вашем сервере, жмутся. Отправил скриншот по почте, смотрите столбикиSIZE(KB)иGZIP(KB)Гм, ещё одно предположение, видимо, дело в фаероволе или прокси, который режет нужные http-заголовки, в о всяком случае так на работе. У меня столбик GZIP пустой. Правда, тогда непонятно, почему так выборочно. Надо будет ещё раз дома посмотреть. Кстати, посмотрел и на вашем сайте, та же ситуация. Т.е. можно сделать вывод, что проблемы не на моём и вашем сервере, а на моей клиентской машине. Высылаю и вам скриншот.
Не смотрите на мой сайт. Хостер давно изменил конфигурацию, теперь вся статика отдается фронтендом nginx, на который я не могу повлиять. На рабочих серверах с Apache 2.0 и Apache 2.2 mod_deflate работает без нареканий.
Конфигурация: apache2.2, tomcat6.0.26, cms OpenCMS (jsp, java). Перепробовал все варианты (что смог найти) для
httpd.conf, не жмется ничего. Что можно проверить, может что ещё в настройка исправить?mod_deflate собран при сборке Apache? Максимальная детальность ErrorLog’а Apache включена?
Apache под windows. Просто установили его, и всё. Включение (убиранием
#вhttpd.conf) модулей mod_expires.so, mod_headers.so отрабатывается.Добавьте директивы mod_deflate, не заключая их в
<IfModule mod_deflate.c>...</IfModule>. Если модуль не доступен, Apache не запустится, а вhttpd-error.logдобавится сообщение об ошибке.P.S.: Надеюсь, что Вы не забыли раскомментировать строку
#LoadModule deflate_module ... /mod_deflate.so.Apachе запустился. Ошибки нет, как и сжатия.
Я никогда не использовал Apache под Windows, поэтому не знаю, чем еще Вам помочь
Так как Apche настроен для работы с виртуальными хостами, то и все эти настройки нужно производить(прописывать) в рамках этого тега. Я думаю это верно и для других систем.
Можно глобально, можно для каждого виртуального хоста. Я не вижу оснований не использовать mod_deflate для каких-то хостов, поэтому всегда включаю его глобально. А теги как раз и спасают от ошибок, связанных с отстутствием модуля.
SetOutputFilter DEFLATE
SetEnvIfNoCase Request_URI \.(?:rar|zip)$ no-gzip dont-vary
SetEnvIfNoCase Request_URI \.(?:gif|jpg|png)$ no-gzip dont-vary
SetEnvIfNoCase Request_URI \.(?:avi|mov|mp4)$ no-gzip dont-vary
SetEnvIfNoCase Request_URI \.mp3$ no-gzip dont-vary
</IfModule
В данном коде отсутствует закрывающая скобка (последний символ), сразу не обратил внимание, когда сервер ругнулся, вот тогда и выявил недочет.
Очень полезно раз и навсегда приучить себя к заглядыванию в логи после изменения конфигурации и перезапуска сервера. Такой подход позволит сэкономить массу времени