Основные понятия кэширования
Кэширование — это процесс хранения часто используемых данных или ресурсов во временном хранилище, таком как память или диск, для ускорения их извлечения в будущем. Кэширование в веб-приложениях может включать различные типы данных или ресурсов, например HTML-страницы, таблицы стилей CSS, файлы JavaScript, изображения и ответы API.
Преимущества кэширования в веб-приложениях
Обслуживая кэшированные данные вместо повторной выборки или вычисления одних и тех же данных из исходного источника, кэширование может значительно сократить время отклика и повысить общую производительность веб-приложений. Это приводит к:
- Улучшенная производительность, ускоренная загрузка страниц делают работу пользователей удобнее
- Снижение нагрузки на сервер, меньшее использование полосы пропускания, экономия средств и улучшенная масштабируемость
Общий код состояния ответа http для кэшированных ресурсов
- 200 OK
При пустом кеше или без кеша запрошенный ресурс отправляется обратно со статусом 200
OK
2. 200 ОК (из кеша памяти)
Запрошенный ресурс уже кэширован в памяти и все еще свеж, поэтому он возвращается из памяти. Обычно, когда вы закрываете браузер и снова открываете ту же страницу, вы больше этого не увидите.
3. 200 ОК (из кеша диска)
Запрошенный ресурс уже был кэширован на диске в какой-то момент и все еще свеж, поэтому он возвращается с диска. Обычно, когда вы закрываете браузер и снова открываете ту же страницу, вы снова видите это.
4. 304 Не изменено
Код ответа перенаправления клиента HTTP
304 Not Modified
указывает, что нет необходимости повторно передавать запрошенные ресурсы. Это неявное перенаправление на кешированный ресурс. Бывает:
1. Если метод запроса является безопасным, например
GET
илиHEAD
ИЛИ
2. Когда запрос является условным и использует заголовок
If-None-Match
илиIf-Modified-Since
.
Некоторые часто запрашиваемые заголовки http для кэширования
Заголовок HTTP Expires
содержит дату/время, после которого ответ считается просроченным.
Недопустимые даты истечения срока действия со значением 0 представляют дату в прошлом и означают, что срок действия ресурса уже истек.
Примечание. Если в ответе есть заголовок
Cache-Control
с директивойmax-age
илиs-maxage
, заголовокExpires
игнорируется.
Cache-Control
— заголовок http1.1, Expires
— заголовок http1.0
2. Заголовки управления кешем
Поле общего заголовка Cache-Control
используется для указания директив для механизмов кэширования как в запросах, так и в ответах. Директивы кэширования являются однонаправленными. Ниже приведены наиболее часто задаваемые директивы. Полный список можно найти здесь.
- нет магазина
no-store
означает, что любые кэши любого типа (частные или общие) не должны хранить этот ответ.
- без кеша
no-cache
не означает «не кэшировать», это означает, что он должен пройти повторную проверку на сервере перед использованием кэшированного ресурса.
- max-age=‹секунды›
max-age
Указывает максимальное количество времени, в течение которого ресурс будет считаться свежим. Эта директива относится ко времени запроса, тогда как Expires
указывает срок действия по Гринвичу.
- необходимо пройти повторную проверку
must-revalidate
не означает "должен пройти повторную проверку", это означает, что локальный ресурс может использоваться, если он моложе предоставленного max-age
, в противном случае он должен пройти повторную проверку.
3. Прагма
Общий заголовок HTTP/1.0 Pragma
используется для обратной совместимости с кэшами HTTP/1.0, где заголовок Cache-Control
HTTP/1.1 еще отсутствует. Он включает только одну директиву no-cache
.
Две пары: Last-Modified/If-Modified-Since и Etag/If-None-Match
Last-Modified/If-Modified-Since и Etag/If-None-Match — это две пары. Обычно вы увидите ту или иную пару.
- Последнее изменение/если изменение с момента
HTTP-заголовок ответа Last-Modified
содержит дату и время, когда исходный сервер считает, что ресурс был изменен в последний раз. Он используется в качестве валидатора, чтобы определить, совпадает ли ресурс с ранее сохраненным. Менее точный, чем заголовок ETag
, это запасной механизм. Условные запросы, содержащие заголовки If-Modified-Since
или If-Unmodified-Since
, используют это поле.
Он используется следующим образом:
Last-Modified: <day-name>, <day> <month> <year> <hour>:<minute>:<second> GMT Last-Modified: Wed, 21 Oct 2015 07:28:00 GMT
HTTP-заголовок запроса If-Modified-Since
делает запрос условным: сервер возвращает запрошенный ресурс со статусом 200
только в том случае, если последний раз он был изменен после указанной даты. Если с тех пор ресурс не изменялся, ответ представляет собой 304
без какого-либо тела; заголовок ответа Last-Modified
предыдущего запроса содержит дату последней модификации. В отличие от If-Unmodified-Since
, If-Modified-Since
можно использовать только с GET
или HEAD
.
Он используется следующим образом:
If-Modified-Since: <day-name>, <day> <month> <year> <hour>:<minute>:<second> GMT If-Modified-Since: Wed, 21 Oct 2015 07:28:00 GMT
2. Etag/Если-Нет-совпадения
Заголовок ответа HTTP1.1 ETag
(или тег объекта) является идентификатором конкретной версии ресурса. Это позволяет кэшам быть более эффективными и экономить пропускную способность, поскольку веб-серверу не нужно повторно отправлять полный ответ, если содержимое не было изменено. Кроме того, etags помогают предотвратить перезапись одновременных обновлений ресурса друг другом (коллизии в воздухе).
Если ресурс по указанному URL-адресу изменяется, новое значение Etag
должно генерироваться. Их сравнение может определить, совпадают ли два представления ресурса.
Он используется следующим образом:
ETag: W/"<etag_value>" ETag: "<etag_value>" ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4"
Если не совпадает
Заголовок HTTP-запроса If-None-Match
делает запрос условным. Для методов GET
и HEAD
сервер вернет запрошенный ресурс со статусом 200
, только если у него нет ETag
, соответствующего заданным. Для других методов запрос будет обработан только в том случае, если ETag
существующего ресурса не соответствует ни одному из перечисленных значений.
Когда условие не выполняется для методов GET
и HEAD
, сервер должен вернуть код состояния HTTP 304 (не изменено). Для методов, применяющих изменения на стороне сервера, используется код состояния 412 (сбой предварительного условия). Обратите внимание, что сервер, генерирующий ответ 304, ДОЛЖЕН генерировать любое из следующих полей заголовка, которые были бы отправлены в ответе 200 (ОК) на тот же запрос: Cache-Control, Content-Location, Date, ETag, Expires и Vary.
При сравнении с сохраненным ETag
используется слабый алгоритм сравнения, означающий, что два файла считаются идентичными, если их содержимое эквивалентно — они не обязательно должны быть идентичными побайтно. Например, две страницы, которые отличаются датой создания в нижнем колонтитуле, все равно будут считаться идентичными.
ПРИМЕЧАНИЕ. Отслеживание Last-Modifed/If-Modified-Since вплоть до секунд,Etag может быть более точным, чем секунды.
Когда и ETag, и Last-Modified, какой из них следует использовать?
Согласно RFC2616, клиент HTTP 1.1 ДОЛЖЕН использовать ETag в любых условных запросах кэша, и если присутствуют как ETag, так и Last Modified, он ДОЛЖЕН использовать оба. Заголовок ETag считается надежным средством проверки (см. раздел 13.3.3), если сервер явно не объявил его слабым, тогда как заголовок Last Modified считается слабым, если между ним и заголовком Date не существует хотя бы незначительной разницы. Обратите внимание, однако, что сервер не обязан отправлять ни то, ни другое (но он ДОЛЖЕН, если может).
Обратите внимание, что клиент не проверяет заголовки, чтобы увидеть, изменились ли они; он просто слепо использует их в следующем условном запросе; Сервер должен оценить, отправлять ли запрошенный контент или ответ 304 Not Modified. Если сервер отправляет только один, то клиент будет использовать только его (хотя для запроса диапазона полезны только сильные валидаторы). Конечно, также на усмотрение промежуточных кешей (если им не запрещено кэширование с помощью директив управления кешем) и сервера относительно того, как они будут действовать в отношении заголовков; RFC заявляет, что они НЕ ДОЛЖНЫ возвращать 304 Not Modified, если валидаторы не согласованы, но, поскольку значения заголовков генерируются сервером, у него есть небольшая свобода действий.
Во второй части мы оценим некоторые общие настройки кэша для разных типов ресурсов и сценариев.