./comments
./contacts telegram: @stikname
email: ;

Настройка сжатия и кэширования на хостинге с Nginx и Apache

Советы и рекомендации
Настройка предварительного сжатия и браузерного кэширования на сервере с Nginx и Apache


На не слишком загруженных сайтах благодаря браузерному кэшированию и предварительному сжатию данных можно и вовсе обойтись без плагинов кэширования. Однако в этом посте даны директивы, которые актуальны только для хостинга, на котором работает HTTP-сервер Apache. Некоторые хостеры ради экономии серверных ресурсов отключают Apache или вовсе не устанавливают его, предпочитая настраивать только менее прожорливый веб-сервер Nginx. Давайте посмотрим, как можно настроить предварительное сжатие и браузерное кэширование, если на вашем хостинге работает только Nginx.

Проверить скорость загрузки страниц вы можете с помощью сервиса Pingdom Tools.


1. Предварительное сжатие
Перед тем, как отдать содержимое страниц в браузер посетителя, можно его сжать. Сжатие уменьшает размер передаваемых файлов (иногда в несколько раз), что приводит к увеличению скорости загрузки страниц и уменьшению исходящего трафика. Сжимать нужно только файлы, содержащие текстовую часть - текст, HTML, PHP, JS, XML, и прочие подобные. Текст хорошо сжимается даже при низком уровне компрессии, объем передаваемых фалов уменьшается на 50-80%. Конечно, файлы небольшие, всего десятки килобайт, но если учесть, что таких фалов тысячи, и загружаются они тысячами посетителей каждый день, то, как говорят, с миру по нитке - нищему на воротник, экономия получается существенная.

1-1. Предварительное сжатие / Apache
Для тех, у кого установлен Apache, нужно узнать у хостера, какие специальные модули, реализующие его, установлены - mod_pagespeed или mod_deflate? Обычно в Apache 2x устанавливают mod_deflate. Есть еще mod_gzip, но его устанавливали в предыдущих версиях, так что его встретить маловероятно.

Если установлен модуль mod_pagespeed, то в файл .htaccess, находящийся в корне вашего сайта, нужно вставить:
<IfModule pagespeed_module>
ModPagespeed on
# using commands,filters etc
</IfModule>


Если установлен модуль mod_deflate, то то в файл .htaccess, находящийся в корне вашего сайта, нужно вставить:
<ifModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/html text/plain text/xml application/xml application/xhtml+xml text/css text/javascript application/javascript application/x-javascript
</ifModule>

В данном случае сжатию подвергаются все текстовые файлы - txt, html, xml, xhtml, css, js.

Или в httpd.conf находящийся в /usr/local/ets/Apache22/:
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE application/javascript
AddOutputFilterByType DEFLATE application/x-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>

После чего обязательно нужно перезапустить апач
/usr/local/etc/rc.d/apache22 restart


1-2. Предварительное сжатие / Nginx
Если хостинг работает под управлением Nginx, то директивы будут выглядеть иначе. В файл .htaccess, находящийся в корне вашего сайта, нужно вставить:
server {
gzip on;
gzip_types text/html text/css application/x-javascript text/plain text/xml image/x-icon;
}


1-3. Предварительное сжатие / Скрипт
Бывает так, что сервер, обеспечивающий работу вашего блога, не поддерживает mod_deflate или mod_gzip. В этом случае можно прибегнуть к универсальному скрипту, который работает и на Apache, и на Nginx.

В основном файле используемого вами движка, в самое его начало, первой строкой нужно вставить:
function isClientSupportGzip() {
if ( headers_sent() || connection_aborted() ) return false;
if ( stripos( getenv( "HTTP_ACCEPT_ENCODING" ), "gzip" ) === false ) return false;
if ( stripos( getenv( "HTTP_USER_AGENT" ), "konqueror" ) !== false ) return false;
return true;
}

if (isClientSupportGzip()) {
ob_start( "ob_gzhandler" );
}
else {
ob_start();
}

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

2. Браузерное кэширование
Наряду со сжатием можно давать браузеру команду использовать кэшированную копию. Зачем каждый раз качать файлы с сайта, если они не с момента последнего посещения не изменились? Лучше отслеживать изменения файлов, и скачивать только те, которые им подверглись, а те, что остались с последнего захода на сайт не измененными, брать их кэша. Этот способ позволяет существенно сократить трафик между браузером посетителя и хостингом сайта, что приводит к сокращению времени загрузки страниц. Особенно заметен прирост в скорости на страницах с картинками. Действительно, картинки меняются на сайте очень редко, и зачем их каждый раз закачивать, есди они уже есть в кэше браузера?

2-1. Браузерное кэширование / установки заголовков / Apache
Apache обеспечивает браузерное кэширование с помощью модулей mod_expires и mod_headers: mod_expires определяет время актуальности кэшированных данных, а mod_headers - их публичную доступность. Совместная работа приводит к гибкой проверке данных перед скачиванием: браузер получает специальные заголовки, по ним определяет, устарели ли данные, которые находятся у него в кэше с момента последнего посещения страницы, и если они устарели, то обновляет их, закачивания новые версии файлов, а если не устарели, то отображает файлы из своего кэша, не скачивая с сервера.

Если у вас работает Apache, для установки заголовков Expires добавьте в файл .htaccess:
<ifModule mod_expires.c>
ExpiresActive On
ExpiresDefault "access plus 5 seconds"
ExpiresByType image/x-icon "access plus 2592000 seconds"
ExpiresByType image/jpeg "access plus 2592000 seconds"
ExpiresByType image/png "access plus 2592000 seconds"
ExpiresByType image/gif "access plus 2592000 seconds"
ExpiresByType application/x-shockwave-flash "access plus 2592000 seconds"
ExpiresByType text/css "access plus 604800 seconds"
ExpiresByType text/javascript "access plus 216000 seconds"
ExpiresByType application/javascript "access plus 216000 seconds"
ExpiresByType application/x-javascript "access plus 216000 seconds"
ExpiresByType text/html "access plus 600 seconds"
ExpiresByType application/xhtml+xml "access plus 600 seconds"
</ifModule>

В данном случае актуальность кэша для разных фалов указана в секундах.

Если у вас работает Apache, для установки для установки заголовка Cache-control добавьте в файл .htaccess:
<ifModule mod_headers.c>
<filesMatch "\.(ico|jpe?g|png|gif|swf)$">
Header set Cache-Control "public"
</filesMatch>
<filesMatch "\.(css)$">
Header set Cache-Control "public"
</filesMatch>
<filesMatch "\.(js)$">
Header set Cache-Control "private"
</filesMatch>
<filesMatch "\.(x?html?|php)$">
Header set Cache-Control "private, must-revalidate"
</filesMatch>
</ifModule>

В данном случае проверяется актуальность в кэше файлов ico, jpg, jpeg, png, gif, swf, css, js, html, xhtml, php.

2-2. Браузерное кэширование / Nginx
Если у вас нет Apache, но есть Nginx, то для того, чтобы указать браузеру брать закэшированные данные, нужно вставить в конфиг nginx следующие строки:
location ~* \.(jpg|png|gif|jpeg|css|js)$ {
expires 24h;
}

В данном случае актуальность кэша 24 часа, а типы проверяемых файлов указаны перечислением - jpg, png, gif, jpeg, css, js.

Вот собственно и все основы, удачного ускорения ваших сайтов! ;)
20.02.2013 11:17:52
stk
7026
5
Комментарии

Barada
30.07.2015 00:44:47
На сколько я помню, у нжинкса нет файла .htaccess - этот файл актуален для апача. Наверное, вы имели в виду виртуальный хост ?
stk
30.07.2015 03:53:45
Точно, действительно ошибка. Спасибо, поправил.
trifan112233
10.09.2016 14:25:32
Спасибо за статью, все заработало !
stk
11.09.2016 14:37:32
trifan112233, это отлично! :)
pavel
20.03.2017 21:44:24
Привет ребята, может не по теме но хотел спросить, может кто поможет, у меня проблема, с различных ip на различные страницы моего сайта поступает один и тот же get запрос (ддос атака), выглядит он так "GET /%7B HTTP/1.0" может кто знает как и что нужно прописать в nginx что бы все ip с этим запросом блокировались?