Эффективная схема кэширования сайта в браузере обеспечивает высокую скорость загрузки веб-страниц при повторных обращениях к ним.
Содержание
Что такое кэш браузера и кэширование сайта?
Кэш браузера (Browser Cache) — временные файлы ресурсов веб-страниц сайта, сохраняемые браузером для последующего отображения в нём при повторном обращении к соответствующим страницам.
Процесс определения и сохранения кэша в браузере называется браузерным кэшированием (Browser Caching).
Браузерное кэширование можно представить следующим образом:
- клиент (браузер) формирует и отправляет запрос на сервер;
- сервер формирует ответ и отправляет веб-страницу и все файлы, с ней связанные, в браузер;
- браузер отображает веб-страницу, при этом кэширует определённые её ресурсы.
При повторных запросах этой веб-страницы браузер будет использовать файлы из кэша сайта. Срок кэширования определяется браузером согласно ответу сервера относительно каждого отдельного типа файла.
Как кэш браузера влияет на скорость загрузки сайта?
Правильная настройка кэширования веб-страниц позволяет значительно увеличить скорость загрузки сайта за счёт:
- Уменьшение объёма загружаемых данных при повторных обращениях.
Если настроить ответ сервера на кэширование всех типов данных, то объём передаваемой информации может быть снижен вплоть до 0 МБ: в таком случае веб-страница будет полностью формироваться из кэша. - Снижение нагрузки на сервер.
Чем меньше данных обрабатывает и передаёт сервер, тем выше его производительность в текущий момент.
Кроме этого, браузерное кэширование значительно экономит веб-трафик клиента, исключая повторное скачивание файлов (картинок, скриптов, стилей) — они будут браться из кэша сайта.
Благодаря кешированию пользователи, повторно посещающие ваш сайт, тратят меньше времени на загрузку страниц.
Google Developers
Как проверить кэширование сайта в браузере?
Существует ряд способов проверки браузерного кэширования ресурсов сайта:
Проверка в браузере Chrome
Первый способ: обратиться к инструментам веб-разработчика, предоставляемым самим браузером. Рассмотрим на примере браузера Chrome:
- Откройте в браузере любую страницу сайта.
- Активируйте панель инструментов разработчика.
Клавиши по умолчанию:Ctrl
+Shift
+I
. - Активируйте вкладку Network.
- Обновите страницу.
Клавиши по умолчанию:Ctrl
+F5
.
Если файл кэшируется, то в колонке Size вместо размера файла будет отображаться запись (from memory cache) или (from disk cache):
Обратите внимание, насколько уменьшился объём передаваемых данных из примера на картинках: 3.8 МБ при первичном обращении и 601 КБ при повторном. При этом скорость загрузки страницы сайта снизилась с 12.45 до 7.77 секунд.
Активируйте чекбокс Disable cache во вкладке Network в панели инструментов Chrome, чтобы просмотреть исходный размер и скорость загрузки ресурсов веб-страницы при первичном обращении к ней.
Сервис PageSpeed Insights
Сервис от Google при обнаружении проблем с кэшированием ресурсов проверяемой веб-страницы выдаёт рекомендацию «Используйте кеш браузера». При клике по ссылке «Как исправить?» развернется список файлов, для которых необходимо оптимизировать настройки кэширования в браузере:
Сервис Pingdom Website Speed Test
Pingdom Website Speed Test — качественный популярный сервис проверки скорости загрузки сайта. Подобно сервису PageSpeed Insights, он указывает на проблемы со скоростью загрузки и даёт свои рекомендации. Каждому фактору сервис присваивает определённый рейтинг (Grade).
Фактор кэширования файлов в браузере называется «Leverage browser caching»:
Какие файлы сайта должны кэшироваться?
Ресурсы веб-страниц делятся на 2 группы:
- Динамические
- Эти ресурсы не хранятся на сервере, а генерируются его средствами при запросах веб-страниц. К таким ресурсам обычно относят HTML-код, который может генерироваться посредством PHP на серверах Apache.
- Статические
- Такие ресурсы хранятся на сервере. Как правило, к ним относится медиа-контент (картинки и видео), а также файлы стилей, скриптов и шрифтов
Для большинства сайтов подходит схема кэширования всех статических ресурсов.
Заголовки кеширования должны применяться ко всем кешируемым статическим ресурсам, а не только к некоторым из них (например, изображениям). Кешируемые ресурсы включают файлы JavaScript и CSS, графические и другие файлы (мультимедийное содержание, файлы PDF и т. д.). Обычно код HTML не является статическим ресурсом и по умолчанию не считается кешируемым.
Google Developers
Сроки кэширования файлов в браузере
Возможной проблемой может быть обновление на сайте статических ресурсов, для которых установлен большой срок хранения в кэше.
Например, разработчик может обновить CSS-свойства в файлах стилей и HTML-код, но в кэше браузера пользователей могут храниться старые CSS-файлы. В результате пользователи при обращении к веб-странице могут видеть искаженный дизайн, т. к. HTML-код будет обновлен, но потерявший актуальность файл стилей будет загружаться из кэша сайта, ведь для него установлен большой срок хранения.
Чтобы избежать подобных проблем, необходимо настроить браузерное кэширование, правильно определив сроки хранения типов файлов.
Продолжительность хранения статических ресурсов в кеше должна составлять не менее недели. Внешние ресурсы (объявления, виджеты и др.) должны храниться не менее 1 дня.
Google Developers
Сроки кэширования файлов определяют значения специальных HTTP-заголовков:
Заголовок Expires
Кэширование по этой схеме происходит иначе: при первичном запросе сервер отдаёт каждый кэшируемый ресурс веб-страницы с HTTP-ответом Expires
, в качестве значения которого указывается дата истечения срока его хранения в кэше. Например:
Expires: Thu, 21 Apr 2016 03:17:22 GMT
До момента наступления этой даты файл будет браться из кэша сайта в браузере. Такая схема исключает лишние запросы к серверу, сравнивающие кэшированный файл с файлом на сервере, но неудобство может быть вызвано привязкой к определённой дате, ведь файл может быть обновлён на сервере до её наступления.
Заголовок Cache-Control
Браузерное кэширование по схеме HTTP-заголовка Cache-Control
является наиболее гибким и актуальным.
Схема выглядит так: сервер передаёт HTTP-ответ Cache-Control
, содержащий директиву max-age
, в качестве значения которой указывается срок кэширования файла в секундах. Например:
Cache-Control: max-age=3600
Пока не пройдёт указанное время с момента получения файла, он будет браться из кэша браузера.
Директивы заголовка Cache-Control
Заголовок Cache-Control
может содержать одну или несколько директив, перечисленных через запятую. Это позволяет управлять кэшированием файлов более гибко.
Директива max-age
Как указывалось выше, с помощью этой директивы сервер даёт знать браузеру, на какой срок можно кэшировать файл. В качестве значения применяется цифра, обозначающая количество секунд.
Единица времени | Количество секунд |
---|---|
Секунда | 1 |
Минута | 60 |
Час | 3600 |
Сутки | 86400 |
Неделя | 604800 |
Месяц | 2592000 |
Год | 31536000 |
Директива no-cache
Cache-Control: no-cache
Вопреки названию, браузер будет кэшировать файл, переданный сервером с данным заголовком. Однако прежде, чем в дальнейшем брать его из кэша, браузер должен делать запрос к серверу на проверку его изменений. Если файл на сервере не изменился, браузер заберёт его из кэша, в ином случае сервер передаст обновлённую версию файла.
Директива no-store
Cache-Control: no-store
Эта директива запрещает сохранять файл браузеру и в других промежуточных кэшах (CDN, прокси-сервера).
Директива public
Cache-Control: public, max-age=3600
Эта директива разрешает кэшировать файл как в браузере пользователя, так и в промежуточных кэшах (CDN, прокси-сервера). Применяется по умолчанию.
Директива private
Cache-Control: private, max-age=3600
Директива private
разрешает кэшировать файл только в браузере пользователя, но не в промежуточных кэшах (CDN, прокси-сервера). Обычно применяется для кэширования персональных данных, актуальных для конечного пользователя.
Сравнение версий файлов в кэше и на сервере
Схему кэширования могут определять HTTP-заголовки для сравнение версий файлов в кэше и на сервере:
Заголовки Last-Modified и If-Modified-Since
Данную схему кэширования можно представить следующим образом:
Браузер делает первичный запрос веб-страницы.
Сервер отдаёт ресурсы (файлы) страницы вместе с HTTP-заголовками
Last-Modified
, содержащими даты создания (изменения) соответствующих ресурсов. Например:Last-Modified: Thu, 21 Apr 2016 03:17:22 GMT
Полученные файлы кэшируются браузером.
При последующих запросах данной страницы браузер для каждого кэшируемого файла посылает HTTP-запрос
If-Modified-Since
, в качестве значения которого указывается дата, которую содержал HTTP-ответ сервераLast-Modified
при предыдущем обращении к нему. Например:If-Modified-Since: Thu, 21 Apr 2016 03:17:22 GMT
Если значения
If-Modified-Since
иLast-Modified
совпадают, сервер отправляет браузеру ответ в виде значения304 (Not Modified)
: файл не претерпел изменений, и его можно брать из кэша. В ином случае сервер вновь передаёт файл в браузер.
К минусам данной схемы кэширования можно отнести постоянные проверяющие актуальность файлов HTTP-запросы If-Modified-Since
к серверу.
Заголовки ETag и If-None-Match
Данная схема кэширования полностью идентична указанной выше схеме, но вместо HTTP-заголовков Last-Modified
и If-Modified-Since
, в качестве значений которых указывались даты создания (изменения) файлов, здесь соответственно применяются заголовки ETag
и If-None-Match
, содержащие произвольный набор символов, который меняется при изменении самого файла. Например:
ETag: "58ca9df6-564"
Недостатком данной схемы также являются постоянные проверяющие запросы If-None-Match
к серверу.
Правильная схема кэширования файлов в браузере
В идеале браузерное кэширование должно функционировать следующим образом:
- сервер отправляет файл клиенту при первичном запросе;
- клиент кэширует файл на срок, определённый в HTTP-заголовке ответа сервера;
- по истечении срока клиент делает запрос к серверу на проверку изменений файла;
- если файл не менялся, он вновь берётся из кэша.
При отсутствии HTTP-заголовков, определяющих схему кэширования файлов, она будет осуществляться браузером по умолчанию.
Если применять только заголовки Last-Modified
или ETag
, то браузер каждый раз будет посылать серверу запросы на сравнение версий файлов.
Если применять только заголовки Expires
или Cache-Control: max-age
, то по окончании срока кэширования браузер будет запрашивать файл на скачивание не зависимо от того, претерпел ли он изменения.
Поэтому ответ сервера для кэшируемого файла должен содержать два заголовка, определяющих эффективную схему кэширования:
- заголовок, определяющий срок кэширования (
Expires
илиCache-Control: max-age
); - заголовок, определяющий изменение файла (
Last-Modified
илиETag
).
Для всех кешируемых ресурсов нужно обязательно указывать один заголовок из пары Expires и Cache-Control max-age, а также один заголовок из пары Last-Modified и ETag.
Google Developers
Такой подход исключает лишние запросы к серверу за счет установленного срока кэширования (определённого с помощью заголовка Expires
или Cache-control: max-age
), а также исключает повторное скачивание ресурса по окончании срока кэширования за счет его проверки на наличие изменений (с помощью заголовков Last-Modified
или ETag
).
Включение и настройка кэширования сайта в браузере
Настройка браузерного кэширования осуществляется посредством редактирования конфигурационных файлов сервера (httpd.conf, .htaccess, nginx.conf).
Модуль mod_expires для сервера Apache
Для формирования HTTP-заголовков Expires
, определяющих дату окончания срока кэширования ресурса, на серверах Apache применяется модуль mod_expires.
Не вдаваясь в подробности синтаксиса настройки данного модуля, приведем пример готовой конфигурации по включению браузерного кэширования на сайте с комментариями в коде:
<IfModule mod_expires.c> # активация формирования заголовков Expires ExpiresActive on # Кэширование по умолчанию 1 месяц ExpiresDefault "access plus 1 month" # Не кэшировать HTML, текст, XML, JSON ExpiresByType text/html "access plus 0 seconds" ExpiresByType text/xml "access plus 0 seconds" ExpiresByType application/xml "access plus 0 seconds" ExpiresByType application/json "access plus 0 seconds" # Кэшировать фиды на 1 час ExpiresByType application/rss+xml "access plus 1 hour" ExpiresByType application/atom+xml "access plus 1 hour" # Кэшировать Favicon 1 год ExpiresByType image/x-icon "access plus 1 year" # Кэшировать картинки и видео 1 месяц ExpiresByType image/gif "access plus 1 month" ExpiresByType image/png "access plus 1 month" ExpiresByType image/jpg "access plus 1 month" ExpiresByType image/jpeg "access plus 1 month" ExpiresByType video/ogg "access plus 1 month" ExpiresByType audio/ogg "access plus 1 month" ExpiresByType video/mp4 "access plus 1 month" ExpiresByType video/webm "access plus 1 month" # Кэшировать файлы шрифтов 1 неделю ExpiresByType application/x-font-ttf "access plus 1 month" ExpiresByType font/opentype "access plus 1 month" ExpiresByType application/x-font-woff "access plus 1 month" ExpiresByType image/svg+xml "access plus 1 month" ExpiresByType application/vnd.ms-fontobject "access plus 1 month" # Кэшировать CSS и JS 1 год ExpiresByType text/css "access plus 1 year" ExpiresByType text/javascript "access plus 1 year" ExpiresByType application/javascript "access plus 1 year" </IfModule>
Скопируйте данный код в файл .htaccess
для включения кэширования файлов в браузере.
Если настройки не вступят в силу, необходимо обратиться в техническую поддержку хостинга: возможно, модуль mod_expires не активирован на сервере.
Подробности о синтаксисе и настройках модуля mod_expires можно узнать в официальной документации.
Модуль mod_headers для сервера Apache
Для формирования HTTP-заголовков Cache-Control
на серверах Apache применяется модуль mod_headers.
Настройка модуля подразумевает использование регулярных выражений для определения типов файлов, для которых будут формироваться заголовки Cache-Control
:
<ifModule mod_headers.c> # Не кэшировать PHP, HTML, XML <FilesMatch "\.(php|html|htm|xml)$"> Header set Cache-Control "no-store, no-cache, max-age=0" </FilesMatch> # Кэшировать изображения 1 месяц <FilesMatch "\.(gif|ico|jpg|jpeg|png|svg)$"> Header set Cache-Control "max-age=2592000" </FilesMatch> # Кэшировать CSS и JS 1 неделю <FilesMatch "\.(js|css)$"> Header set Cache-Control "max-age=604800" </FilesMatch> # Кэшировать шрифты 1 месяц <FilesMatch "\.(woff|woff2|eot|otf|ttf)$"> Header set Cache-Control "max-age=2592000" </FilesMatch> </ifModule>
Указанный выше код можно скопировать в файл .htaccess
для применения настроек кэширования файлов к конкретному сайту.
Если настройки не вступят в силу, неободимо обратиться в техническую поддержку хостинга: возможно, модуль mod_headers не активирован на сервере.
Подробности о синтаксисе и настройках модуля mod_headers можно узнать в официальной документации.
Модуль ngx_http_headers_module для сервера Nginx
Для определения схемы кэширования на сервере Nginx применяется модуль ngx_http_headers_module, позволяющий настраивать любые заголовки ответов сервера.
Настройка заголовков Expires на Nginx
server { # Отменить кэширование PHP, HTML, XML location ~* \.(php|xml|html|htm)$ { expires off; } # Установить срок кэширования картинок на 1 месяц location ~* \.(gif|ico|jpeg|png|svg)$ { expires 1m; } # Установить срок кэширования CSS и JS на 1 неделю location ~* \.(css|js)$ { expires 1w; } # Установить срок кэширования шрифтов на 1 месяц location ~* \.(css|js)$ { expires 1m; } }
Настройка заголовков Cache-Control на Nginx
server { # Не кэшировать PHP, HTML, XML location ~* \.(php|xml|html|htm)$ { add_header Cache-Control "no-store"; } # Кэшировать изображения 1 месяц location ~* \.(gif|ico|jpeg|png|svg)$ { add_header Cache-Control "max-age=2592000"; } # Кэшировать CSS и JS 1 неделю location ~* \.(css|js)$ { add_header Cache-Control "max-age=604800"; } # Кэшировать файлы шрифтов 1 месяц location ~* \.(woff|woff2|eot|otf|ttf)$ { add_header Cache-Control "max-age=2592000"; } }
Указанный выше код можно скопировать в файл nginx.conf
для применения данных настроек к сайту.
Если настройки не вступят в силу, необходимо обратиться в техническую поддержку хостинга: возможно, модуль ngx_http_headers_module не активирован на сервере.
Подробности о синтаксисе и настройках модуля ngx_http_headers_module можно узнать в официальной документации.
Проверка HTTP-заголовков ответа сервера
Проверить заголовки ответа сервера после (или до) включения кэширования в .htaccess
(или другом конфигурационном файле) позволяют стандартные средства современных браузеров: установка дополнительных плагинов не требуется.
Рассмотрим процесс проверки передаваемых сервером заголовков на примере Chrome:
- Откройте в браузере любую страницу сайта.
- Активируйте панель инструментов разработчика.
Клавиши по умолчанию:Ctrl
+Shift
+I
. - Активируйте вкладку Network.
- Обновите страницу.
Клавиши по умолчанию:Ctrl
+F5
. - Кликните по интересующему ресурсу из списка.
- Изучите HTTP-заголовки, отобразившиеся в правой колонке.