Сжатие ответов Веб-сервера 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. Ситуация для всех остальных каскадных таблиц стилей и скриптов на языке JavaScript полностью аналогична — в зависимости от исходного размера они сжаты в два-четыре раза.

Заключение

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

Понравилась статья?

 Подпишитесь на RSS или почтовую рассылку

 Присоединяйтесь в Google+ или Twitter

 Поделитесь ссылкой в социальной сети или блоге

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

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


  2. AddOutputFilterByType DEFLATE application/javascript
    AddOutputFilterByType DEFLATE text/javascript
    AddOutputFilterByType DEFLATE text/css

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

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

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

  4. Посмотрел в Apache файл mime.types, там есть строки:

    application/javascript js
    . . .
    #text/javascript

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

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

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

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

            • Попробуйте удалить код <IfModule mod_deflate.c> ... </IfModule> из .htaccess и добавить его в httpd.conf, а затем перезапустить Apache.

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

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

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

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

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

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

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

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

      • 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.

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

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


  7. 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

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

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

  8. Вопрос: на одном из моих сайтов в .htaccess прописано следующее:

    AddOutputFilterByType DEFLATE text/html
    BrowserMatch ^Mozilla/4 gzip-only-text/html
    BrowserMatch ^Mozilla/4\.0[678] no-gzip
    BrowserMatch \bMSIE !no-gzip !gzip-only-text/html

    а в одном из php-скриптов у меня есть строки:

    if ( file_exists('cache/somefile.gz.html') )
    {
      header('Content-Encoding: gzip');
      readfile('cache/somefile.gz.html');
    }

    т.е. cache/somefile.gz.html уже сжатый.

    Вопрос: когда я запускаю этот скрипт, файл отображается нормально, размер сжатый, но я хочу знать, не пытается ли Apache еще раз сжать его на выдаче, или он видит, что Content-Encoding и так gzip и не применяет к нему сжатие?

      • Думал, может, вы знаете… Логи эти попробовал: пишет Internal server error. То, что мы задаем типы я помню, просто я ведь передаю text/html, просто Content-Encoding у него gzip, вот и интересно, понимает ли Apache его как сжатый.

            • Они создают наиболее непредсказуемый софт, имеющий массу «недокументированных особенностей». А Apache имеет отличную подробную официальную и неофициальную документацию.

  9. Добавил первый вариант в файл .htaccess на сайт, и сайт заглох полностью, вернул предыдущий файл .htaccess, не помогло. Как исправить ваш совет?

    • Судя по двум добавленным ссылкам, Вы СЕОшник? Вот и занимайтесь СЕО, не стоит лезть в конфигурации серверов. Я, например, не врач, поэтому не пытаюсь лечить людей. Если восстановление старого .htaccess не помогло, ко мне какие вопросы?

  10. Сергей, можете помочь с настройкой сжатия? Уже столько способов перепробовал и ничего не получается.

  11. Здравствуйте! Всё прочитал но так и не нашёл ответа на свой вопрос.
    Apache/2.2.23 (как я понимаю нет mod_filters? есть mod_ext_filter)
    Когда добавляю 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

    Сжимается всё кроме js и css, подскажите куда копать? PS: У меня VPS.

    • Добрый день! mod_filters нет, но он и не нужен. Возможно, VPS настроен так, что статический контент отдается, например, nginx’ом, либо стоят какие-то ограничения на использование директив mod_deflate для снижения нагрузки на сервер. В случае VPS это мало вероятно, но других причин (при отсутствии ошибок) я не вижу 😕

  12. В PageSpeed Insight до вставки этих директив:

    Сжатие .../assets/nls-1468926876-min.js позволит уменьшить размер на 128.0Кб (на 64%).
    Сжатие .../fonts/pt_sans_bold_italic-webfont.ttf позволит уменьшить размер на 60.0Кб (на 50%).
    Сжатие .../fonts/pt_sans_bold-webfont.ttf позволит уменьшить размер на 54.3Кб (на 49%).
    Сжатие .../fonts/pt_sans-webfont.ttf позволит уменьшить размер на 51.9Кб (на 48%).
    Сжатие .../fonts/pt_sans_italic-webfont.ttf позволит уменьшить размер на 42.9Кб (на 46%).
    Сжатие .../fonts/leaguegothiccyrillic-webfont.ttf позволит уменьшить размер на 31.7Кб (на 50%).
    Сжатие .../assets/nls1945646755-min.css позволит уменьшить размер на 31.3Кб (на 77%).
    Сжатие .../GetDepartCities?... позволит уменьшить размер на 318б (на 50%).

    После включения:

    Сжатие .../assets/nls-1468926876-min.js позволит уменьшить размер на 128.0Кб (на 64%).
    Сжатие .../assets/nls1945646755-min.css позволит уменьшить размер на 31.3Кб (на 77%).
    Сжатие .../GetDepartCities?... позволит уменьшить размер на 309б (на 49%).

    И ещё, даже когда директив на сжатие в .htaccess вообще нет, сама страница всё-равно пакуется gzip. Прошёлся по всему httpd.conf хоть я и не силён в Linux, но ничего там похожего на настройку gzip не нашёл… Может это наведёт Вас на мысли?!

    • Мысль одна, хостинг настроен на отдачу статики с помощью nginx. Внимательно посмотрите ответ сервера. И, кстати, mod_deflate может делать как deflate-, так и gzip-сжатие. Кроме этого, существуют всяческие zlib и т.д., но эти вещи настраиваются на уровне конфигурации интерпретатора PHP и CMS сайта.
      P.S.: Я не люблю СПАМ, поэтому здесь не будет ни одной ссылки на темы, отличные от тем сайта 😉

  13. Извиняюсь за ссылки, и в мыслях не было, простой копипаст из Page Speed. Ссылку на сайт тоже убрал. А подсказать не можете где смотреть как настроен nginx, потому что на уровне CMS Yii framework ничего не настраивал.

    • Посмотрите тип сервера в заголовках HTTP. Если там есть nginx, общайтесь с хостером, только учтите, что, скорее всего, он не будет ничего исправлять.

  14. Здравствуйте!
    Подскажите пожалуйста. Уже какое-то время пытаюсь найти указания на то, какой модуль лучше использовать для сжатия: mod_gzip.c или mod_deflate.c. Вроде в инетах пишут, что это два равнозначных модуля и нужно выбрать какой-то один. Рекомендуют — mod_deflate.c. Типа он входит в стандартную поставку Апача. Рекомендуют такой .htaccess файл.
    В нем одновременно присутствуют директивы и для модуля mod_gzip.c и для модуля mod_deflate.c

    mod_gzip_on Yes
    mod_gzip_dechunk Yes
    mod_gzip_item_include file .(html?|txt|css|js|php|pl)$
    mod_gzip_item_include mime ^text.*
    mod_gzip_item_include mime ^application/x-javascript.*
    mod_gzip_item_include mime ^application/x-font-woff.*
    mod_gzip_item_exclude mime ^image.*
    mod_gzip_item_exclude rspheader ^Content-Encoding:.*gzip.*
    AddOutputFilterByType DEFLATE text/text text/html text/plain text/xml text/css application/x-javascript application/javascript

    А как такое Апач может проглотить? Если, допустим такая ситуация, что у него оба модуля установлены — он выполнит сжатие только каким-то одним модулем? Как он выберет — каким? Или он сожмет сначала одним, а потом вторым?

    • В последних версиях Apache нет модуля mod_gzip, все делается через mod_deflate. Кстати, чем он Вас не устроил?

  15. Не то чтобы не устроил. Просто в инетах в половине статей по оптимизации страниц методом сжатия gzip идут инструкции для mod_gzip.c, а в другой для mod_deflate.c. Я чайник и мне потребовалось время, чтоб разобраться — что это два разных модуля. Сам гугл, кажется, давал ссылку на документацию апача и там я не смог найти mod_gzip.c вообще. Куча статей в инете типа mod_gzip.c vs mod_deflate.c. Но из них непонятно было как обстоит ситуация на сегодняшний день. А по той ссылке, что я приводил — вообще соломоново решение приняли — включили оба. как это будет работать при наличии на сервере обоих методов, наверное, никто не знает. Автор прокомментировал так: Нет, будет выбран только один минимизатор, не знаю какому апач отдает приоритет. Рекомендую deflate, т.к. gzip это инструмент, который содержит deflate. У меня сложилось впечатление, что он немного «плавает» в этой теме

    • Время идет, статьи становятся неактуальными, да и авторы все разные, не всегда понятно, что они хотели сказать 🙂

  16. Я обращался к совему хостеру с вопросом какие инструкции мне использовать в .htaccess для mod_gzip.c или mod_deflate.c. Там видно попался не очень опытный человек. Он сказал, что сжатие уже включено и сославлся на whatsmyip.org. Я так понимаю, это какое-то сжатие на стороне ngincs что ли. Потому как гугл никакого сжатия не видел. И порекомендовал мне в .htaccess вписать оба. если сайт отвалиться по 500 ошибке, тогда инструкции убрать. Я вставил mod_deflate.c. гугл — тут же снял свои жалобы на отсутсвие сжатия. но whatsmyip.org никакой разницы не показал.

Оставить комментарий