Поддержание свежести данных с помощью устаревших обновлений

Дополнительный инструмент, который поможет вам сбалансировать оперативность и актуальность при обслуживании вашего веб-приложения.

stale-while-revalidate помогает разработчикам балансировать между оперативностью ( немедленная загрузка кэшированного контента ) и актуальностью (гарантируя, что обновления кэшированного контента будут использоваться в будущем) . Если вы поддерживаете стороннюю веб-службу или библиотеку, которая обновляется по регулярному графику, или ваши собственные ресурсы, как правило, имеют короткий срок жизни, то stale-while-revalidate могут быть полезным дополнением к вашим существующим политикам кэширования.

Поддержка установки stale-while-revalidate вместе с max-age в заголовке ответа Cache-Control доступна в Chrome 75 и Firefox 68 .

Браузеры, которые не поддерживают stale-while-revalidate будут молча игнорировать это значение конфигурации и использовать max-age , как я вскоре объясню…

Что это значит?

Давайте разобьем stale-while-revalidate на две части: идея о том, что кэшированный ответ может быть устаревшим, и процесс повторной проверки.

Во-первых, как браузер узнает, является ли кэшированный ответ «устаревшим»? Заголовок ответа Cache-Control , который содержит stale-while-revalidate также должен содержать max-age , а количество секунд, указанное через max-age определяет устаревание. Любой кэшированный ответ старше max-age считается свежим, а более старые кэшированные ответы — устаревшими.

Если локально кэшированный ответ еще актуален, его можно использовать как есть для выполнения запроса браузера. С точки зрения stale-while-revalidate в этом сценарии делать нечего.

Но если кэшированный ответ устарел, выполняется еще одна проверка на основе возраста: находится ли возраст кэшированного ответа в дополнительном временном окне, предусмотренном настройкой stale-while-revalidate ?

Если в это окно попадает возраст устаревшего ответа, то он будет использован для выполнения запроса браузера. В то же время к сети будет отправлен запрос «повторной проверки» таким образом, чтобы не задерживать использование кэшированного ответа. Возвращенный ответ может содержать ту же информацию, что и ранее кэшированный ответ, или может отличаться. В любом случае ответ сети сохраняется локально, заменяя все, что было ранее в кеше, и сбрасывая таймер «свежести», используемый во время любых будущих сравнений max-age .

Однако, если устаревший кэшированный ответ достаточно стар и выходит за пределы временного stale-while-revalidate , он не выполнит запрос браузера. Вместо этого браузер получит ответ из сети и будет использовать его как для выполнения первоначального запроса, так и для заполнения локального кэша свежим ответом.

Живой пример

Ниже приведен простой пример HTTP API для возврата текущего времени, а точнее, текущего количества минут после часа.

В этом сценарии веб-сервер использует этот заголовок Cache-Control в своем ответе HTTP:

Cache-Control: max-age=1, stale-while-revalidate=59

Этот параметр означает, что если запрос времени повторяется в течение следующей 1 секунды, ранее кэшированное значение все равно будет свежим и будет использоваться как есть, без какой-либо повторной проверки.

Если запрос повторяется через 1–60 секунд, кэшированное значение будет устаревшим, но будет использоваться для выполнения запроса API. В то же время «в фоновом режиме» будет сделан запрос на повторную проверку для заполнения кэша новым значением для будущего использования.

Если запрос повторяется более чем через 60 секунд, устаревший ответ вообще не используется, и как выполнение запроса браузера, так и повторная проверка кэша будут зависеть от получения обратного ответа из сети.

Вот разбивка этих трех различных состояний, а также временной интервал, в котором каждое из них применяется в нашем примере:

Диаграмма, иллюстрирующая информацию из предыдущего раздела.

Каковы распространенные случаи использования?

Хотя приведенный выше пример для службы API «минут после часа» является надуманным, он иллюстрирует ожидаемый вариант использования — службы, которые предоставляют информацию, которую необходимо обновить, но где некоторая степень устаревания приемлема.

Менее надуманными примерами могут быть API для текущих погодных условий или заголовки главных новостей, написанных за последний час.

Как правило, любой ответ, который обновляется через известный интервал, вероятно, будет запрошен несколько раз и является статическим в пределах этого интервала, является хорошим кандидатом для краткосрочного кэширования с помощью max-age . Использование stale-while-revalidate в дополнение к max-age увеличивает вероятность того, что будущие запросы могут быть выполнены из кэша с более свежим контентом без блокировки ответа сети.

Как он взаимодействует с работниками сферы обслуживания?

Если вы слышали об stale-while-revalidate скорее всего, это было в контексте рецептов, используемых в сервисном работнике .

Использование устаревшего при повторной проверке через заголовок Cache-Control имеет некоторые сходства с его использованием в сервисном работнике, и применяются многие из тех же соображений, касающихся компромиссов между актуальностью и максимальным сроком службы. Однако есть несколько соображений, которые следует принять во внимание при принятии решения о том, следует ли реализовать подход на основе сервисного работника или просто полагаться на конфигурацию заголовка Cache-Control .

Используйте подход сервисного работника, если…

  • Вы уже используете сервис-воркера в своем веб-приложении.
  • Вам нужен детальный контроль над содержимым ваших кешей, и вы хотите реализовать что-то вроде политики истечения срока действия, которая использовалась реже всего. В этом может помочь модуль Expiration Cache Expiration Workbox.
  • Вы хотите получать уведомления, когда устаревший ответ изменяется в фоновом режиме на этапе повторной проверки. В этом может помочь модуль обновления широковещательного кэша Workbox.
  • Такое поведение stale-while-revalidate необходимо во всех современных браузерах.

Используйте подход Cache-Control, если…

  • Вы бы предпочли не иметь дело с накладными расходами на развертывание и поддержку сервис-воркера для вашего веб-приложения.
  • Вы можете позволить автоматическому управлению кэшем браузера предотвратить слишком большой размер локальных кэшей.
  • Вас устраивает подход, который в настоящее время поддерживается не всеми современными браузерами (по состоянию на июль 2019 г.; поддержка может расшириться в будущем).

Если вы используете сервис-воркера, а также включили stale-while-revalidate для некоторых ответов через заголовок Cache-Control , то сервис-воркер, как правило, будет иметь «первую возможность» ответить на запрос. Если сервис-воркер решит не отвечать или если в процессе генерации ответа он сделает сетевой запрос с помощью fetch() , то поведение, настроенное через заголовок Cache-Control в конечном итоге вступит в силу.

Узнать больше

Изображение героя Сэмюэля Зеллера.