Включить сжатие gzip и кэширование в Nginx и Apache

Включить сжатие gzip и кэширование в Nginx и Apache

Сейчас, все браузеры поддерживают сжатия (картинок, файлов), т.к. он является частью спецификации протокола HTTP 1.1. Такое сжатие, а именно сжатие текстовых форматов (например CSS, Javascipt или HTML) сможет уменьшить их объем до 70%. Работает это следующим образом:

Прежде чем отправить ответ, сервер выполняет сжатие данных, при получения сжатого ответа от сервера браузер выполняет обратную процедуру и разжимает сжатый контент и выводит результат.

gzip в nginx и apache

И в своей теме «Включить сжатие gzip в Nginx и Apache» я расскажу как можно настроить веб-сервер (apache или  nginx) с поддержкой сжатия.

Сжатие на веб-сервере Nginx

Если используете Linux (Debian/Ubuntu/Mint или CentOS/RedHat/Fedora) то путь к файлу конфигурации будет:

# vim /etc/nginx/nginx.conf

При использовании FreeBSD путь к файлу конфигурации лежит в:

# vim /usr/local/etc/nginx/nginx.conf

Если хотите использовать сжатие, то необходимо в файл сервера или в отдельный виртуальный хост прописать следующие строки:

#GZIP
 gzip on;
 gzip_min_length 1000;
 gzip_proxied expired no-cache no-store private auth;
 gzip_types text/plain application/xml;
# Выделяем буфер для gzip
 gzip_buffers 32 4k;
# Устанавливаем уровень сжатия, от 1-9
 gzip_comp_level 9;
# Убираем поддержку IE6
 gzip_disable "msie6";
# Устанавливаем версию для использования gzip (1.0 или 1.1)
 gzip_http_version 1.1;
# Разрешаем использовать статику
 gzip_static on;
 gzip_vary on;
 gzip_types text/css text/javascript text/xml text/plain text/x-component application/javascript application/x-javascript application/json application/xml application/rss+xml font/truetype application/x-font-ttf font/opentype application/vnd.ms-fontobject image/svg+xml;

Кэширование в Nginx

Так же, настраиваем кэширование (которое включается с опцией expires) для заголовки для картинок и статических файлов в nginx. Мой конфиг выглядит следующим образом:

# Хранить кэш 24ч\1 сутки
 expires 86400s;
# Добавляем заголовки (хеадеры)
 add_header Pragma public;
 add_header Cache-Control "max-age=86400, public, must-revalidate, proxy-revalidate";
 #add_header "X-UA-Compatible" "IE=Edge,chrome=1";

# Правила rewrite для версированного CSS + JS через дериктиву filemtime
 location ~* ^.+\.(css|js)$ {
 rewrite ^(.+)\.(\d+)\.(css|js)$ $1.$3 last;
# Задаем сколько будет храниться кэш 
 expires 31536000s;
# Выключаем логирование 
 access_log off;
 log_not_found off;
# Добавляем заголовки (хеадеры)
 add_header Pragma public;
 add_header Cache-Control "max-age=31536000, public";
 }

# Агрессивное кэширование для статических файлов
 location ~* \.(asf|asx|wax|wmv|wmx|avi|bmp|class|divx|doc|docx|eot|exe|gif|gz|gzip|ico|jpg|jpeg|jpe|mdb|mid|midi|mov|qt|mp3|m4a|mp4|m4v|mpeg|mpg|mpe|mpp|odb|odc|odf|odg|odp|ods|odt|ogg|ogv|otf|pdf|png|pot|pps|ppt|pptx|ra|ram|svg|svgz|swf|tar|t?gz|tif|tiff|ttf|wav|webm|wma|woff|wri|xla|xls|xlsx|xlt|xlw|zip)$ {
# Задаем сколько будет храниться кэш 
 expires 31536000s;
# Выключаем логирование 
 access_log off;
 log_not_found off;
# Добавляем заголовки (хеадеры)
 add_header Pragma public;
 add_header Cache-Control "max-age=31536000, public";
 }

Это включит кэш на веб-сервере на максимальный период для всех  перечисленных файлов.

Сжатие на веб-сервере Apache

По умолчанию модуль mod_deflate должен быть включен в apache. Но лучше убедиться и выполнить проверку и поискать следующую строку в конфиге веб-сервера apache:

LoadModule deflate_module modules/mod_deflate.so

Мы можем определить, какие типы файлов нужно сжать:

AddOutputFilterByType DEFLATE text/html text/plain text/css application/javascript

Пропишите следующую конфигурацию в виртуальный хост Apache  и это включит сжатие mod_deflate для вашего сайта.

<Directory /var/www/html/>
<IfModule mod_mime.c>
 AddType application/x-javascript .js
 AddType text/css .css
</IfModule>
<IfModule mod_deflate.c>
 # Compress HTML, CSS, JavaScript, Text, XML and fonts
 AddOutputFilterByType DEFLATE application/javascript
 AddOutputFilterByType DEFLATE application/rss+xml
 AddOutputFilterByType DEFLATE application/vnd.ms-fontobject
 AddOutputFilterByType DEFLATE application/x-font
 AddOutputFilterByType DEFLATE application/x-font-opentype
 AddOutputFilterByType DEFLATE application/x-font-otf
 AddOutputFilterByType DEFLATE application/x-font-truetype
 AddOutputFilterByType DEFLATE application/x-font-ttf
 AddOutputFilterByType DEFLATE application/x-javascript
 AddOutputFilterByType DEFLATE application/xhtml+xml
 AddOutputFilterByType DEFLATE application/xml
 AddOutputFilterByType DEFLATE font/opentype
 AddOutputFilterByType DEFLATE font/otf
 AddOutputFilterByType DEFLATE font/ttf
 AddOutputFilterByType DEFLATE image/svg+xml
 AddOutputFilterByType DEFLATE image/x-icon
 AddOutputFilterByType DEFLATE text/css
 AddOutputFilterByType DEFLATE text/html
 AddOutputFilterByType DEFLATE text/javascript
 AddOutputFilterByType DEFLATE text/plain
 AddOutputFilterByType DEFLATE text/xml
 #The following line is enough for .js and .css
 AddOutputFilter DEFLATE js css
 AddOutputFilterByType DEFLATE text/plain text/xml application/xhtml+xml text/css application/javascript application/xml application/rss+xml application/atom_xml application/x-javascript application/x-httpd-php application/x-httpd-fastphp text/html
</IfModule>
<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 mod_headers.c> 
 Header append Vary User-Agent env=!dont-vary
</IfModule> 
<ifModule mod_gzip.c>
 mod_gzip_on Yes
 mod_gzip_dechunk Yes
 mod_gzip_item_include file .(html?|txt|css|js|php|pl)$
 mod_gzip_item_include handler ^cgi-script$
 mod_gzip_item_include mime ^text/.*
 mod_gzip_item_include mime ^application/x-javascript.*
 mod_gzip_item_exclude mime ^image/.*
 mod_gzip_item_exclude rspheader ^Content-Encoding:.*gzip.*
</ifModule>
</Directory>

Используем кеш на стороне браузера в Apache

Как только пользователь откроет сайт будут скачиваться не только код страницы с html страницы, и так же  css, картинки, js. И одно открытие страницы файла обращается  к серверу от нескольких десятков и аж до нескольких сотен! такие запросы очень нагружают  сервер,  и так же дают дополнительное время на загрузку страницы у пользователя.

Создаем файлик .htaccess в своей домашней директории сайта и добавляем:

# кеширование в браузере на стороне пользователя
<IfModule mod_expires.c>
 #Включаем поддержку директивы Expires
  ExpiresActive On
 # Задаем время для хранения файлов (картинок) в кэше для каждого типа 
  ExpiresDefault "access 7 days"
  ExpiresByType application/javascript "access plus 1 year"
  ExpiresByType text/javascript "access plus 1 year"
  ExpiresByType text/css "access plus 1 year"
  ExpiresByType text/html "access plus 7 day"
  ExpiresByType text/x-javascript "access 1 year"
  ExpiresByType image/gif "access plus 1 year"
  ExpiresByType image/jpeg "access plus 1 year"
  ExpiresByType image/png "access plus 1 year"
  ExpiresByType image/jpg "access plus 1 year"
  ExpiresByType image/x-icon "access 1 year"
  ExpiresByType application/x-shockwave-flash "access 1 year"
</IfModule>
# Cache-Control
<ifModule mod_headers.c>
# Задаем 30 дней для данного типа файла
<filesMatch "\.(ico|pdf|flv|jpg|jpeg|png|gif|swf)$">
  Header set Cache-Control "max-age=2592000, public"
</filesMatch>

# Задаем 30 дней для данного типа файла
<filesMatch "\.(css|js)$">
 Header set Cache-Control "max-age=2592000, public"
</filesMatch>

# Задаем 2 дня для данного типа файла
<filesMatch "\.(xml|txt)$">
Header set Cache-Control "max-age=172800, public, must-revalidate"
</filesMatch>

# Задаем 1 день для данного типа файла
<filesMatch "\.(html|htm|php)$">
 Header set Cache-Control "max-age=172800, private, must-revalidate"
</filesMatch>
</ifModule>

# использование кеша браузеров
FileETag MTime Size
<ifmodule mod_expires.c>
<filesmatch ".(jpg|jpeg|gif|png|ico|css|js)$">
 ExpiresActive on
 ExpiresDefault "access plus 1 year"
</filesmatch>
</ifmodule>

#Запрет отдачи HTTP-заголовков Vary браузерам семейства MSIE
<IfModule mod_setenvif.c>
 BrowserMatch "MSIE" force-no-vary
 BrowserMatch "Mozilla/4.[0-9]{2}" force-no-vary
</IfModule>

Проверка gzip и кэширования в Nginx и Apache

Создаем тестовый файл php_info.php в домашней директории вашего сайта со следующими строками:

<?php
phpinfo();
?>

И открыв его в браузере по ссылке вида http://host_or_IP/php_info.php посмотреть что есть в поле “Loaded Modules“, вы должны увидеть там что-то вроде:

Использование кеша на стороне браузера apache

Использование кеша на стороне браузера apache

Если в списке нет mod_expires или mod_headers  – выполните в консоли сервера (подключившись по ssh) по очереди следующие команды (это установит/включит mod_expires, mod_headers):

# a2enmod headers
# a2enmod expires
# service apache2 restart

Для индексной странички видим, что gzip включён, но для URL из js нет:

$ curl -I -H 'Accept-Encoding: gzip,deflate' https://linux-notes.org/ | grep gzip

А после добавления gzip_types получаем такое:

$ curl -I -H 'Accept-Encoding: gzip,deflate' https://linux-notes.org/test/test.js

ИЛИ еще:

# curl --header "Accept-Encoding: gzip,deflate,sdch" -I https://linux-notes.org

HTTP/1.1 200 OK
Server: nginx
Date: Thu, 25 Jun 2015 11:27:22 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
Vary: Accept-Encoding
Set-Cookie: wfvt_3183169984=558be599d6523; expires=Thu, 25-Jun-2015 11:57:21 GMT; path=/; httponly
X-Pingback: https://linux-notes.org/xmlrpc.php
X-UA-Compatible: IE=edge,chrome=1
Expires: Fri, 26 Jun 2015 11:27:22 GMT
Cache-Control: max-age=86400
Pragma: public
Cache-Control: max-age=86400, public, must-revalidate, proxy-revalidate
Content-Encoding: gzip

Проверка Gzip онлайн ресурсами

Теперь, как на сайт были внесены изменения, давайте протестируем онлайновым инструментом, чтобы убедиться что GZIP работает правильно.

http://checkgzipcompression.com/
http://www.whatsmyip.org/http-compression-test/

На этом все, я завершаю свою тему «Включить сжатие gzip и кэширование в Nginx и Apache».

15 thoughts on “Включить сжатие gzip и кэширование в Nginx и Apache

  1. Вопрос: Настроил по вашему мануалу как есть для теста, но nginx отдает кеш даже под авторизованным пользователем. Настроил кеш на 6 мин и пока он не сбросится, юзер будет юзать сайт как под анонимом, а после выхода из сессии сайт выглядит для пользователя как для залогиненного, как разделить?)

    • Используете CMS? Если да, то для входа в админку нужно создать блок и прописать в него хеадеры + включать сжатие или выключить его вообще. Нужно смотреть по обстоятельствам. Расскажите что используете более подробно, а я помогу Вам.

      • Да, сайт работает на cms Drupal версия 8
        Vps в digitalocean Debian 8 nginx+php-fpm+postgresql.
        Ваш мануал пока единственный , который заработал сразу, vps настраивал сам.
        Сайт у меня не статический, там публикуются статьи и комментируются, то есть присутствует динамика. И хорошо бы хотя бы настроить этот кеш для анонимов. В друпале есть своё встроенное кеширование, но по сравнению с тем как кеширует сам nginx то земля и небо. Загрузка старницы с кеширвоанием nginx 23ms, а с кешированием друпала около секунды. Есть специальные модули для кеширования в друпал и многие устанавливают их, но использовать их не хочу. Хочется научиться делать это средствами сервера и только потом если этого будет мало, перейти уже к расширению кеширования с помощью модулей.

        • Это хорошо что мои статьи помогают людям. Я пишу их с разных источников, проверяю работу и после чего делюсь с людьми. У меня много статей есть полезных в черновиках, но не хватает времени и рук на все. Если есть желания, у кого-то, то можете помогать с написанием полезных статей на разные темы (Unix/Linux) желательно которых нет еще на сайте. Помогайте развивать проект.

          • А у меня сервер не запускается с этим кодом в Opencart

  2. Отличная статья, только nginx не запускается при применении настроек агрессивного кэширования. Никак не могу гугл инсайт дать положительную оценку. Всё ссылается на «Используйте кеш браузера» Как еще можно настроить? Подскажите пожалуйста.

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

      • Да супер материалы, очень доступны начинающим. Я совсем недавно перешел на VDS ну и столкнулся, что по теме для новичков очень мало понятных материалов.
        Ошибка следующая

        2016/01/23 11:20:25 [emerg] 385#0: «location» directive is not allowed here in /etc/nginx/nginx.conf:56

        А еще хотел спросить как все таки победить кэш? Чтобы гугл инсайт не ругался, что я его не использую.
        Еще по сжатию картинок webp
        Скрипт установил на сайт, но не пойму как его запустить.

      • Прочитал, что location может быть в директиве server только. А как выглядит полностью у вас конфиг? Может быть директива вынесена за отображаемый код? Просто вне директивы ее использование невозможно и будет давать ошибку при запуске.

  3. А как быть если используется связка Apache2 + nginx? Нужно настраивать сжатие для каждого сервера?

    • Смотря для чего/что сжимать. Если картинки, то на стороне nginx нужно сжимать ( т.к он работает со статикой).

  4. Добрый день! А вот это куда прописывать?

    Пропишите следующую конфигурацию в виртуальный хост Apache и это включит сжатие mod_deflate для вашего сайта.

    • Прописывать в виртуальный хост. Так же, я поправил конфиг для сжатия ( апач) и сейчас все должно работать. Спасибо за замечание!

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Этот сайт использует Akismet для борьбы со спамом. Узнайте как обрабатываются ваши данные комментариев.