Сжатие ответов Веб-сервера Apache средствами модуля mod_deflate

Apache Эта заметка продолжает статьи Краткое руководство по 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 завершается с не самым приятным результатом High priority, все каскадные таблицы стилей и скрипты на языке JavaScript отдаются Веб-сервером в несжатом виде, например:

Просмотр объектов сайта до активации модуля mod_deflate

В данном фрагменте списка 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 завершается с результатом Low priority, все каскадные таблицы стилей и скрипты на языке JavaScript отдаются Веб-сервером сжатым, например, для упомянутого выше файла теперь можно увидеть такую информацию:

Просмотр объектов сайта после активации модуля mod_deflate

В данном фрагменте списка Show Resources видно такие изменения, как уменьшение значений Content-Length и Transfer Size более чем в три раза и появление заголовка Content-Encoding, сообщающего, что файл сжат методом gzip. Cитуация для всех остальных каскадных таблиц стилей и скриптов на языке JavaScript полностью аналогична - в зависимости от исходного размера они сжаты в два-четыре раза.

Заключение

Если на Вашем хостинге используется Веб-сервер Apache второго поколения (версий 2.0.xx или 2.2.xx), обязательно посмотрите в сторону использования модуля mod_deflate, т.к. он без каких-либо проблем позволяет более чем в три раза уменьшить объем трафика, генерируемого Вашим сайтом и, соответственно, во столько же раз увеличить скорость отображения Вашего сайта браузерами посетителей. На этом я делаю паузу в рассуждениях об оптимизации производительности Веб-серверов и поздравляю Вас с наступающими праздниками!

IT Talk - Форум о программировании, операционных системах, безопасности, сайтостроении, железе, девайсах, сетях и т.п.

Похожие статьи в рубриках ‘Интересное’ и ‘Оптимизация сайтов’

Комментарии

  1. Антон, 10.01.2011 г. в 21:25

    Хорошая статья, а главное полезная. Спасибо!

  2. because, 12.04.2011 г. в 11:49

    Спасибо за статью, все четко и понятно расписано!

  3. because, 23.05.2011 г. в 11:47

    А не подскажете, в чем отличие !no-gzip и no-gzip. То есть в чем смысл восклицательного знака?

  4. guest, 09.06.2011 г. в 19:54


    AddOutputFilterByType DEFLATE application/javascript
    AddOutputFilterByType DEFLATE text/javascript
    AddOutputFilterByType DEFLATE text/css

    лучше заменить на:

    AddOutputFilterByType DEFLATE text/css text/javascript application/x-javascript

  5. [...] Сжатие ответов Веб-сервера Apache средствами модуля mod_defla… [...]

  6. kastorskiy, 13.07.2011 г. в 12:48

    Добавил в свой .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 не жмуться.
    Не подскажете, куда копать?

  7. kastorskiy, 13.07.2011 г. в 12:50

    Гм, скушались строки из кода. В общем код как в статье.

  8. kastorskiy, 13.07.2011 г. в 12:57

    Посмотрел в апаче файл mime.types
    Там есть строки:
    application/javascript js
    . . .
    #text/javascript

    Добавил в .htaccess application/javascript – всё равно не заработало.

    • SergeySL, 13.07.2011 г. в 13:56

      Все зависит от настроек Apache. Задайте вопрос техподдержке своего хостинга.

      • kastorskiy, 13.07.2011 г. в 14:04

        У меня не хостинг, я арендую выделенный сервер, т.е. сам могу посмотреть или поменять настройки. Вопрос в том, куда смотреть.

        • SergeySL, 14.07.2011 г. в 14:10

          Я не сталкивался с YSlow для Firefox. Воспользуйтесь Google Page Speed, чтобы узнать тип содержимого, который установлен на Вашем Веб-сервере для JS, а затем подкорректируйте .htaccess.

          • kastorskiy, 15.07.2011 г. в 14:07

            Google Page Speed показал Content-Type: application/javascript, что я и внёс в .htaccess, но всё равно не жмётся.

            • SergeySL, 15.07.2011 г. в 14:30

              Попробуйте удалить код ... из .htaccess и добавить его в httpd.conf, а затем перезапустить Apache.

              • kastorskiy, 15.07.2011 г. в 15:25

                Попробую попозже, когда буду дома, но сомневаюсь, что поможет. *.css ведь у меня жмёт, а не жмёт почему-то *.js.

                • SergeySL, 16.07.2011 г. в 13:47

                  Чудес не бывает. Если у Вас нет специфически настроенного фронтенда на базе Apache или nginx, то остается искать несостыковки в конфигурации Apache.

                  • kastorskiy, 18.07.2011 г. в 11:06

                    Как я и предполагал, нечего не изменилось после переноса в httpd.conf. Дальше *.css жмётся, *.js не жмётся. Я не говорил что это чудо, я только предполагал, что предлагаемое решение не решит проблему.

                    • SergeySL, 18.07.2011 г. в 14:48

                      Я предложил вариант, который позволяет обойти различные AllowOverride (не знаю, как они выглядят в Вашем случае) и более предпочтителен для отладки. Пришлите адрес сайта мне в личку.

                    • SergeySL, 18.07.2011 г. в 15:28

                      А с чего это Вы взяли, что у Вас *.js не жмутся? Те, которые лежат на Вашем сервере, жмутся. Отправил скриншот по почте, смотрите столбики SIZE(KB) и GZIP(KB) ;)

  9. kastorskiy, 18.07.2011 г. в 15:48

    Гм, ещё одно предположение, видимо, дело в фаероволе или прокси, который режет нужные http-заголовки, в о всяком случае так на работе. У меня столбик GZIP пустой. Правда, тогда непонятно, почему так выборочно. Надо будет ещё раз дома посмотреть. Кстати, посмотрел и на вашем сайте, та же ситуация. Т.е. можно сделать вывод, что проблемы не на моём и вашем сервере, а на моей клиентской машине. Высылаю и вам скриншот.

    • SergeySL, 18.07.2011 г. в 16:09

      Не смотрите на мой сайт. Хостер давно изменил конфигурацию, теперь вся статика отдается фронтендом nginx, на который я не могу повлиять. На рабочих серверах с Apache 2.0 и Apache 2.2 mod_deflate работает без нареканий.

  10. Вадим, 05.08.2011 г. в 17:08

    Конфигурация: apache2.2, tomcat6.0.26, cms OpenCMS (jsp, java). Перепробовал все варианты (что смог найти) для httpd.conf, не жмется ничего. Что можно проверить, может что ещё в настройка исправить?

    • SergeySL, 05.08.2011 г. в 18:18

      mod_deflate собран при сборке Apache? Максимальная детальность ErrorLog’а Apache включена?

      • Вадим, 05.08.2011 г. в 18:34

        Apache под windows. Просто установили его, и всё. Включение (убиранием # в httpd.conf) модулей mod_expires.so, mod_headers.so отрабатывается.

        • SergeySL, 05.08.2011 г. в 18:46

          Добавьте директивы mod_deflate, не заключая их в <IfModule mod_deflate.c>...</IfModule>. Если модуль не доступен, Apache не запустится, а в httpd-error.log добавится сообщение об ошибке.
          P.S.: Надеюсь, что Вы не забыли раскомментировать строку #LoadModule deflate_module ... /mod_deflate.so.

          • Вадим, 05.08.2011 г. в 19:01

            Apachе запустился. Ошибки нет, как и сжатия.

            • SergeySL, 05.08.2011 г. в 20:10

              Я никогда не использовал Apache под Windows, поэтому не знаю, чем еще Вам помочь :(

              • Вадим, 08.08.2011 г. в 12:17

                Так как Apche настроен для работы с виртуальными хостами, то и все эти настройки нужно производить(прописывать) в рамках этого тега. Я думаю это верно и для других систем.

                • SergeySL, 08.08.2011 г. в 12:37

                  Можно глобально, можно для каждого виртуального хоста. Я не вижу оснований не использовать mod_deflate для каких-то хостов, поэтому всегда включаю его глобально. А теги как раз и спасают от ошибок, связанных с отстутствием модуля.

  11. Den, 08.09.2011 г. в 15:31


    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

    В данном коде отсутствует закрывающая скобка (последний символ), сразу не обратил внимание, когда сервер ругнулся, вот тогда и выявил недочет.

    • SergeySL, 08.09.2011 г. в 20:25

      Очень полезно раз и навсегда приучить себя к заглядыванию в логи после изменения конфигурации и перезапуска сервера. Такой подход позволит сэкономить массу времени ;)

Ваш комментарий

(обязательно)