stale-while-revalidate 策略及其实现

date
Dec 12, 2020
slug
state-while-revaildate
status
Published
tags
Browser
Cache
summary
type
Post

stale-while-revalidate

stale-while-revalidate(简称SWR)是一种由 HTTP RFC 5861 提出的 HTTP 缓存策略。它表示客户端将接受过期的(stale)响应,同时在后台异步检查是否有新的响应。

浏览器本地缓存(local caching)实现

浏览器基于这一份 RFC 有自己的 SWR 实现。它主要依赖于响应头中的 Cache-Control 属性中的 stale-while-revalidate 与 max-age 字段(所对应的值都为秒数)。目前支持浏览器 SWR 缓存的浏览器有 Chrome75(及以上版本)和 Firefox68( 及以上版本)。
浏览器 SWR 缓存策略主要分为两部分:
  1. 判断响应缓存是否过期。
  1. 重新校验响应数据时效性。
浏览器通过 max-age 字段来判断缓存是否过期,缓存时长超过 max-age 的缓存数据会被视为过期。
  1. 如果缓存未过期,则发起请求时将直接从本地拿取数据。
  1. 如果缓存过期,但过期时长未超出 stale-while-revalidate 设定的值,发起请求时浏览器仍然会从本地拿取数据,但是同时它会异步发出重新校验(revalidate)请求。重新校验请求所返回的响应值将为替代之前的响应缓存存于本地,并刷新缓存计时器。
  1. 如果缓存过期,且过期时长超出 stale-while-revalidate 设定的值,浏览器发起请求时会直接请求服务端拿取最新响应数据并刷新本地缓存。

具体例子

假设服务端返回的 Cache-Control 字段如下
Cache-Control: max-age=1, stale-while-revalidate=59
那么在各个时间段内,发起请求时浏览器的具体行为是这样的:
notion image

内存缓存(in-memory caching)实现

与浏览器缓存存于客户端本地不同,第三方库的 SWR 实现方案是内存缓存(in-memory chacing)。目前业内流行的 SWR 请求库有:
  1. React Query - Hooks for fetching, caching and updating asynchronous data in React
  1. SWR – SWR

SWR 的应用场景

针对需要不断刷新但可接受一定程度的延迟的信息服务(例如:当前的天气状况等。),SWR 能够带来快速加载,使这些应用的体验更好。
使用第三方库内存缓存实现的 SWR(以下使用 React Query 为例)——由于请求的动作都是由代码控制——在体验优化层面能带来更多的可能性,例如:
  1. 在同一页面的不同组件多次发起相同的请求,React Query 能 Dedupe 成一个,其他请求的数据均由缓存返回。
  1. 如果同一请求示例在页面中都 unmount 了,那么他们之前请求的响应数据将在内存缓存中保留一定时长(可设置),若在时长范围内又有新的请求示例,那么数据会由缓存返回;若缓存失效,则数据会被回收。

参考资料
 

© Sytone 2021