stale-while-revalidate / swr 一看就懂,一用就会

2024-01-10 12:32:27

介绍

stale-while-revalidate=<seconds>

举例:Cache-control: max-age=10, stale-while-revalidate=60(接口缓存10秒,swr设置为60秒)

mdn解释:表明客户端愿意接受陈旧的响应,同时在后台异步检查新的响应。秒值指示客户愿意接受陈旧响应的时间长度。

可以理解为:当该接口缓存过期后的60秒(60秒为例子中的60)内,再次请求该接口,仍然会立刻返回已经过期的信息,同时也会调用接口向服务器获取最新的数据,并重新保存在缓存中。

为方便理解,stale-while-revalidate可以总结为有三个特性:

  • swr发生在缓存失效后(max-age后)

  • swr会在缓存失效后的一定时间内(swr期间)的第一次请求,仍然会返回老数据

  • swr期间请求接口,浏览器会发请求获取新数据,但不会在本次请求中返回(新数据)

基本流程如下图:

swr基本流程

如果在swr期间请求接口:
请求流程

适用性

swr并不适用于大部分接口

首先swr作为缓存的一种方式,肯定不适合高频更新的内容,如列表数据、详情信息等。

而且swr会在缓存失效后一定时间内仍然返回老数据,虽然只有一次,但因为这个特性,也代表他不适合处理如banner获取、用户信息获取等接口,比如马上新年了,每个在运营的网站基本都会新年当天显示新年快乐的banner,但用户新年当天首次打开页面,却看不到新年祝福,就显得很奇怪。

所以,只适合一些更新频率低,而且对时效性不是很看重的接口,目前想到的只有广告展示这种接口比较适用。

兼容性

stale-while-revalidate目前仍然是实验性功能,并不是缓存标准文档的一部分,下边是它的兼容性(2024年1月截图)

swr兼容性

实操部分

想理解swr到底是什么,建议大家都写一个demo试一试,文章底部我会提供一个接口,供大家练习测试

开始实操:

/swr接口,请求头设置为:"Cache-Control": "max-age=10, stale-while-revalidate=10"

也就是说,该请求会缓存10秒钟,swr10秒钟

下边我对/swr接口发起了多次请求:

swr接口请求

  1. 首次请求:正常返回数据并记入缓存

  2. 在0~10s时间内请求:不向服务端发起请求,直接返回“首次”请求记入的缓存

  3. 第二次请求:直接返回“首次请求”记入的缓存,向服务端发起请求(也就是请求Typetext/html的那次请求),重新把返回的数据记入缓存

  4. 后续请求,在10s内会返回“第二次请求”记入的数据,10s后,再请求会重复(3.)的动作

测试接口:

  • 接口地址:https://blockxu.top/api/swr

  • 缓存设置为:"Cache-Control", "max-age=10, stale-while-revalidate=10"

  • 为更直观的体验swr,接口会延时2秒返回

tips:个人服务器,接口可能并不稳定,不保证一直好用哦~

html文件内容(用跨域浏览器运行):

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>test</title>
</head>
<body>
    <h1 id="box"></h1>
    <button id="button">请求</button>
</body>
<script>
    // 请求
    button.onclick = async () => {
        const res = await fetch('https://blockxu.top/api/swr')
        console.log('res', res)
        // 获取返回内容
        const text = await res.text()
        box.innerHTML = text
    }
</script>
</html>

文章来源:https://blog.csdn.net/block_xu/article/details/135495610
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。