Условное кэширование. Автоматизация кэширования. Уменьшение количества запросов
Условное кэширование
Сброс кэша
Кэширование на серверном уровне
Кэширование XHR-запросов Для динамических ресурсов очень часто оказывается, что обеспечить какой-либо срок кэширования невозможно: содержимое документа постоянно изменяется или полностью зависит от пользовательских действий. Если рассмотреть статические файлы, то и для них бывает весьма полезно настроить проверку изменения ресурса с течением времени. Например, установить срок действия кэша на месяц, а чтобы не увеличивать объем передаваемых данных, через месяц проверять, изменился ли запрашиваемый объект или нет.
В том случае, если объект не изменился, мы можем передать клиенту соответствующий заголовок и не передавать все содержимое объекта (ведь оно уже на клиенте имеется). Такой метод кэширования (когда мы в зависимости от определенных условий передаем в браузер либо полностью содержимое файла, либо отвечаем, что файл не изменился) называется условным кэшированием.
Существует 2 способа обеспечить условное кэширование: при помощи заголовков Last-Modified + If-Modified-Since и ETag + If-None-Match. Первый заголовок в паре относится к ответу со стороны сервера, второй – к запросу со стороны клиента, который уже получил соответствующий ответ сервера и теперь желает проверить, изменилось ли что-нибудь с той поры.
При помощи пары Last-Modified мы можем установить соответствие ресурса только по времени его изменения. ETag (англ. Entity Tag, метка сущности) предполагает более широкую сферу применения: мы можем для ресурса назначить уникальную строку, зависящую не только от времени изменения, но и от других параметров (например, в сжатом виде передается данный файл или нет).
Для отдельных серверов (которые не работают как кластер) более уместной будет настройка именно даты изменения файла. Для более сложных систем необходимо настраивать именно ETag-заголовки, чтобы гарантировать уникальность файла среди множества различных машин.
Давайте, рассмотрим, как передавать и проверять данную пару заголовков на примере динамического содержимого HTML-документа (предполагается, что документ изменяется относительно редко, поэтому мы можем его закэшировать).
/* получаем содержимое документа, например, из закэшированного файла */
$content = @file_get_contents($file);
/* вычисляем уникальную метку, зависящую от содержания */
$hash = md5($content);
/* проверяем соответствие вычисленной и переданной с клиента меток */
if ((isset($_SERVER['HTTP_IF_NONE_MATCH']) &&
stripslashes($_SERVER['HTTP_IF_NONE_MATCH']) == '"' . $hash . '"') ||
(isset($_SERVER['HTTP_IF_MATCH']) &&
stripslashes($_SERVER['HTTP_IF_MATCH']) == '"' . $hash . '"')) {
/* в случае совпадения меток передаем 304-ответ */
header ("HTTP/1.0 304 Not Modified");
/* и не передаем содержимое документа */
header ("Content-Length: 0");
exit();
}
/* во всем остальных случаях выставляем заголовок ETag с меткой */
header("ETag: \"" . $hash . "\"");
/* и отдаем полностью содержимое документа */
echo $content;