Включить сжатие gzip и кэширование в Nginx и Apache
Сейчас, все браузеры поддерживают сжатия (картинок, файлов), т.к. он является частью спецификации протокола HTTP 1.1. Такое сжатие, а именно сжатие текстовых форматов (например CSS, Javascipt или HTML) сможет уменьшить их объем до 70%. Работает это следующим образом:
Прежде чем отправить ответ, сервер выполняет сжатие данных, при получения сжатого ответа от сервера браузер выполняет обратную процедуру и разжимает сжатый контент и выводит результат.
И в своей теме «Включить сжатие 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“, вы должны увидеть там что-то вроде:
Если в списке нет 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' http://linux-notes.org/ | grep gzip
А после добавления gzip_types получаем такое:
$ curl -I -H 'Accept-Encoding: gzip,deflate' http://linux-notes.org/test/test.js
ИЛИ еще:
# curl --header "Accept-Encoding: gzip,deflate,sdch" -I http://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: http://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».
Вопрос: Настроил по вашему мануалу как есть для теста, но nginx отдает кеш даже под авторизованным пользователем. Настроил кеш на 6 мин и пока он не сбросится, юзер будет юзать сайт как под анонимом, а после выхода из сессии сайт выглядит для пользователя как для залогиненного, как разделить?)
Используете CMS? Если да, то для входа в админку нужно создать блок и прописать в него хеадеры + включать сжатие или выключить его вообще. Нужно смотреть по обстоятельствам. Расскажите что используете более подробно, а я помогу Вам.
Да, сайт работает на cms Drupal версия 8
Vps в digitalocean Debian 8 nginx+php-fpm+postgresql.
Ваш мануал пока единственный , который заработал сразу, vps настраивал сам.
Сайт у меня не статический, там публикуются статьи и комментируются, то есть присутствует динамика. И хорошо бы хотя бы настроить этот кеш для анонимов. В друпале есть своё встроенное кеширование, но по сравнению с тем как кеширует сам nginx то земля и небо. Загрузка старницы с кеширвоанием nginx 23ms, а с кешированием друпала около секунды. Есть специальные модули для кеширования в друпал и многие устанавливают их, но использовать их не хочу. Хочется научиться делать это средствами сервера и только потом если этого будет мало, перейти уже к расширению кеширования с помощью модулей.
Это хорошо что мои статьи помогают людям. Я пишу их с разных источников, проверяю работу и после чего делюсь с людьми. У меня много статей есть полезных в черновиках, но не хватает времени и рук на все. Если есть желания, у кого-то, то можете помогать с написанием полезных статей на разные темы (Unix/Linux) желательно которых нет еще на сайте. Помогайте развивать проект.
А у меня сервер не запускается с этим кодом в Opencart
Отличная статья, только 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 только. А как выглядит полностью у вас конфиг? Может быть директива вынесена за отображаемый код? Просто вне директивы ее использование невозможно и будет давать ошибку при запуске.
Спасибо вам большое, Мастер. Пишите ещё! 🙂
А как быть если используется связка Apache2 + nginx? Нужно настраивать сжатие для каждого сервера?
Смотря для чего/что сжимать. Если картинки, то на стороне nginx нужно сжимать ( т.к он работает со статикой).
Добрый день! А вот это куда прописывать?
Пропишите следующую конфигурацию в виртуальный хост Apache и это включит сжатие mod_deflate для вашего сайта.
Прописывать в виртуальный хост. Так же, я поправил конфиг для сжатия ( апач) и сейчас все должно работать. Спасибо за замечание!
Статья что надо, все работает