Оптимизация кеширования сайта браузерами и прокси-серверами

Как я уже говорил, Apache Google Page Speed обеспечивает выполнение двух тестов, предназначенных для анализа тех параметров сайта, которые управляют кешированием статических объектов (каскадных таблиц стилей, скриптов на языке JavaScript и изображений) браузерами и прокси-серверами (Leverage browser caching и Leverage proxy caching). Эта статья является кратким руководством по практическому применению рекомендаций вышеназванных тестов в процессе настройки Веб-сервера Apache.

Введение

Для того, чтобы Google Page Speed не имел ни каких претензий к параметрам, которые отвечают за кеширование статических объектов этого сайта браузерами и прокси-серверами, мне потребовалось активировать такие возможности Веб-сервера Apache, как отдача соответствующих HTTP-заголовков Expires для всех статических объектов, отдача соответствующих HTTP-заголовков Cache-Control для всех статических объектов, запрет отдачи HTTP-заголовков Vary в случае использования браузеров семейства Microsoft Internet Explorer. Все перечисленные функции могут быть реализованы средствами стандартных модулей Веб-сервера Apache mod_expires, mod_headers и mod_setenvif, которые доступны на подавляющем большинстве хостингов.

Отдача HTTP-заголовков Expires для всех статических объектов

HTTP-заголовки Expires предназначены для уведомления браузеров и прокси-серверов о сроках хранения объектов в кеше. До истечения этих сроков браузеры и прокси-серверы используют объекты, сохраненные в кеше, а не загружают их с сайта. Раздел Optimize caching документа Web Performance Best Practices советует установить для всех статических объектов (каскадных таблиц стилей, скриптов на языке JavaScript и изображений) срок хранения в кеше браузеров и прокси-серверов не менее одного месяца, но не более одного года. Для того, чтобы Веб-сервер Apache отдавал соответствующие рекомендациям HTTP-заголовки Expires, необходимо добавить в файл .htaccess, находящийся в корневой папке сайта, или в файл httpd.conf/vhost.conf (в зависимости от конфигурации используемого хостинга), следующие строки:

<IfModule mod_expires.c>
  ExpiresActive On
  ExpiresByType application/javascript "access plus 1 year"
  ExpiresByType text/javascript "access plus 1 year"
  ExpiresByType text/css "access plus 1 year"
  ExpiresByType image/gif "access plus 1 year"
  ExpiresByType image/jpeg "access plus 1 year"
  ExpiresByType image/png "access plus 1 year"
</IfModule>

Данный фрагмент файла конфигурации Веб-сервера Apache проверяет наличие модуля mod_expires и, если модуль mod_expires доступен, включает отдачу HTTP-заголовков Expires, которые устанавливают срок хранения перечисленных выше объектов в кеше браузеров и прокси-серверов равный одному году с момента первой загрузки. Некоторые руководства предлагают поступить проще, заменив строки 3-7 строкой:

ExpiresDefault text/css "access plus 1 year"

Я противник такого подхода, т.к. он затрагивает гораздо больше объектов, чем требуется, и может привести к непредсказуемым последствиям.
Что делать, если нужно обновить какой-либо статический объект раньше, чем истечет срок его хранения в кеше браузеров и прокси-серверов? Если ответить максимально коротко — нужно изменить его URL. Если говорить более подробно, то при разработке сайта следует предусмотреть добавление к URL статических объектов некоторых ключей, которые зависят от версий этих объектов и имеют длину не менее восьми символов (последнее условие необходимо для предотвращении коллизий в подсистеме кеширования браузеров семейства Mozilla Firefox). Такой подход сложнее с точки зрения реализации, однако, он наиболее эффективен с точки зрения удобства поддержки сайта, т.к. позволяет устанавливать большие сроки хранения объектов в кеше браузеров и прокси-серверов и избавляет от проблем, связанных с обновлением этих объектов.

Отдача HTTP-заголовков Cache-Control для всех статических объектов

HTTP-заголовки Cache-Control служат для управления кешированием объектов браузерами и прокси-серверами. Я не буду рассматривать все варианты этих HTTP-заголовков, т.к. они подробно описаны в документе RFC 2616 — Hypertext Transfer Protocol — HTTP/1.1, а ограничусь самым распространенным случаем — использованием значений public и private. HTTP-заголовок Cache-control: public разрешает кеширование объектов прокси-серверами, а HTTP-заголовок Cache-control: private — браузерами. Предпочтительным вариантом является использование HTTP-заголовоков Cache-control: public, однако, из-за некорректной обработки объектов, которые сжимаются с помощью mod_gzip (как правило, это каскадные таблицы стилей и скрипты на языке JavaScript), некоторыми прокси-серверами может возникнуть проблема ошибочной интерпретации HTTP-заголовков Content-Encoding. Эта проблема имеет несколько решений, одним из которых является отдача HTTP-заголовка Cache-control: private для объектов, которые сжимаются с помощью mod_gzip. С учетом сказанного для отдачи требуемых HTTP-заголовков Cache-Control необходимо добавить в один из вышеназванных файлов конфигурации следующие строки:

<IfModule mod_headers.c>
  <FilesMatch .*\.(js|css)$>
    Header set Cache-control: private
  </FilesMatch>
  <FilesMatch .*\.(gif|jpg|png)$>
    Header set Cache-control: public
  </FilesMatch>
</IfModule>

Данный фрагмент файла конфигурации Веб-сервера Apache проверяет наличие модуля mod_headers и, если модуль mod_headers доступен, включает отдачу HTTP-заголовков Cache-Control: private для всех файлов с расширениями .css и .js, а также отдачу HTTP-заголовков Cache-Control: public для всех файлов с расширениями .gif, .jpg и .png.

Запрет отдачи HTTP-заголовков Vary браузерам семейства MSIE

HTTP-заголовки Vary, как и HTTP-заголовки Cache-Control, предназначены для управления кешированием, однако, их использование может вызвать проблему, связанную с тем, что браузеры семейства Microsoft Internet Explorer не выполняют кеширование некоторых объектов, для которых отдаются такие заголовки. Для запрета отдачи HTTP-заголовков Vary в случае использования браузеров семейства Microsoft Internet Explorer необходимо добавить в один из вышеназванных файлов конфигурации следующие строки:

<IfModule mod_setenvif.c>
  BrowserMatch "MSIE" force-no-vary
  BrowserMatch "Mozilla/4.[0-9]{2}" force-no-vary
</IfModule>

Данный фрагмент файла конфигурации Веб-сервера Apache проверяет возможность использования модуля mod_setenvif и, если модуль mod_setenvif доступен, запрещает отдачиу HTTP-заголовков Vary в случае использования браузеров семейства Microsoft Internet Explorer.

Заключение

Я специально не стал рассматривать вопрос изменения тех URL статических объектов, которые содержат Query-String (объекты с такими URL воспринимаются прокси-серверами как динамически изменяемые и не кешируются), т.к. данная процедура индивидуальна для каждого сайта и может потребовать изменение кода CMS / плагинов / тем. Рассмотренные же процедуры просто необходимы и в большинстве случаев достаточны. Они были проверены на нескольких сайтах с разными CMS и во всех случаях привели к уменьшению количества претензий со стороны Google Page Speed, т.к. изменили результаты выполнения тестов Leverage browser caching и Leverage proxy caching на Low priority.

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

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

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

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

Оптимизация кеширования сайта браузерами и прокси-серверами: 18 комментариев

  1. Много прочитал на эту тему в Интернете, но у вас все разложено по полочкам. К сожалению мне не помогло и сжатие тоже не получается. На Денвере все ОК, а на сервере не вышло. Увы… Может поможете?

  2. Пожалуйста помогите включить кэширование на стороне пользователя. Сайт находится; narod.ru. Очень много кодов вставляла для кэширования в файл .htaccess, ничего не меняется.

  3. Спасибо Вам!!! Очень помогла статья. Включил все плечи кэширования (вообще не понял, что сделал, но Google не ругается, и это главное пока). Просто и понятно!

  4. Большое спасибо! Вроде вё включил, но Google не видит. Наверное со стороны хостинга что-нибудь.

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