Thank you for reading this post, don't forget to subscribe!
Клиентское кэширование — это способность браузера сохранять локально файлы, чтобы не делать к ним повторных обращений. Это очень полезно для картинок и CSS/Javascript файлов. Когда человек переходит по страницам браузер постоянно будет запрашивать одни и те же файлы, если не использовать механизм кэширования на браузере.
Управление тем, какие файлы следует кэшировать осуществляется с помощью HTTP заголовков Cache-control и Expires. Сервер отправляет такой заголовок вместе с ответом, указывая браузеру стоит или нет сохранить этот файл в локальное хранилище.
Если файл был сохранен в кэше, то при следующем запросе к файлу, браузер получит его содержимое локально. Таким образом, все произойдет значительно быстрее, т.к. не будет запроса на сервер.
Cache-control
Для того, чтобы управлять кэшированием в браузере используется HTTP заголовок Cache-control. Его необходимо передавать со всеми файлами, которые нужно кэшировать. Он имеет следующий формат:
1 |
Cache-Control: private, max-age=0, no-cache |
- private означает, кто кэширование будет работать только на браузере пользователя. Вместо этого Вы можете использовать инструкцию public. Это разрешает кэширование на публичных прокси-серверах (такие часто есть в компаниях).
- no-cache означает, что данный запрос нельзя кэшировать.
- max-age это время, на которое будет закэширован результат. Устанавливается в секундах.
Обычно этого заголовка достаточно для того, чтобы все заработало:
1 |
Cache-Control: private, max-age=60 |
# закэширует результат запроса в браузере на 60 секунд
1 |
Cache-Control: private, max-age=0, no-cache |
# запретит кэширование запроса
Expires
Дополнительный заголовок HTTP Expires указывает дату и время, когда браузер должен обновить кэш:
1 |
Expires: Thu, 31 Dec 2037 23:55:55 GMT |
# Браузер отправит повторный запрос аж в 2037 году, до этого времени он будет использовать кэш
Этот заголовок следует использовать вместе с Cache-Control.
Vary
Заголовок Vary позволяет установить дополнительные правила для кэширования запросов:
1 |
vary: User-Agent |
# Браузер будет знать, что контент может отличаться в зависимости от версии сайта (например, мобильной и настольной)
Что кэшировать
Кэшируйте все файлы, которые изменяются реже, чем раз в несколько минут. В обязательном порядке:
- Картинки
- CSS
- Javascript
- Загружаемые файлы (архивы, документы и т.п.)
Использование в приложении
В приложении заголовки Cache-Control обычно не используются, т.к. приложения генерируют динамический контент. Если же у Вас редко изменяется сайта, Вы можете добавить кэширование, чтобы снизить количество запросов на сервер. Например, в PHP:
1 2 3 |
<? header("Cache-control: public"); header("Expires: " . gmdate("D, d M Y H:i:s", time() + 60*60) . " GMT"); |
# Включим кэш на 1 час
Однако лучше этого не делать, т.к. при изменении контента у разных посетителей будут разные версии страниц.
Использование на Web сервере
Заголовки для картинок и статических файлов (JS/CSS) нужно устанавливать на Web сервере.
Nginx
В Nginx кэширование включается инструкцией expires:
1 2 3 4 5 6 7 |
server { ... location ~* ^.+\.(ogg|ogv|svg|svgz|eot|otf|woff|mp4|ttf|rss|atom|jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf)$ { <b>expires max;</b> } ... } |
# Включит кэш на бесконечный срок для файлов с перечисленными расширениями
Apache
В Apache кэширование включается модулем mod_expires и выглядит так:
1 2 3 |
<FilesMatch "\.(ogg|ogv|svg|svgz|eot|otf|woff|mp4|ttf|rss|atom|jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf)$"> Header set Cache-Control "max-age=2592000, must-revalidate" </FilesMatch> |
# Включает кэш для файлов на 1 месяц
Изменяемые файлов
Javascript и CSS файлы обычно изменяются. Но заранее невозможно определить когда нужно будет внести изменение. Можно кэшировать такие файлы на короткое время (например минуту), но это не позволит использовать все преимущества Cache-Control.
Браузер хранит в кэше файлы соответственно их адресам URL. Если Мы добавим GET параметр в путь, путь изменится и браузер заново запросит файл. Что нам и нужно. При каждом обновлении CSS и Javascript файлов следует добавлять в GET параметр новое значение:
Лучше всего использовать последовательные числа ( версии), и при каждом изменении просто увеличивать их на единицу:
1 |
<script src="/jquery.js?<b>5</b>"></script> |