前言
Cache Storage 是 Web 开发中一个非常强大的工具,主要用于缓存网络资源,从而提高页面二次加载速度。如果对页面首次加载速度优化感兴趣的,可参考我的另一篇文章:[前端进阶] 首屏优化知识梳理
1. 简介
Cache Storage 用于存储和管理HTTP请求和响应。以请求URL作为key,接口返回的数据作为value。
特点:
-
它与HTTP缓存完全隔离,可以减少带宽,提供离线能力。
-
它是一个异步化的存储方式。
存储空间:
Cache Storage的存储空间大小因浏览器而异。Chrome 的 Cache Storage 存储空间通常为每个站点 分配200MB 到 1GB 之间。具体限制取决于用户的设备和浏览器。
存储时间:
存储时间没有固定的限制,如果用户的设备磁盘空间不足,系统可能会清理缓存以释放空间。所以需要手动清理旧缓存,防止占用空间
2. 创建缓存对象
通过caches.open创建缓存对象
js
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</link>
</head>
<body>
<script>
//判断浏览器是否支持缓存
if ("caches" in window) {
caches.open("cache-name").then((cache) => {
console.log('cache', cache)
//在缓存对象中进行操作
})
}
</script>
</body>
</html>
使用VSCode插件Live Server启动服务,可以从浏览器控制面板中看到Cache Storage存储位置
3. 增加缓存
1. cache.add
cache.add会发起一个 fetch 请求,并将请求成功的结果自动存储到缓存中
js
cache.add(request).then(() => {
// request 已经添加到 cache
});
示例:
js
if ("caches" in window) {
caches.open("cache-name").then((cache) => {
//在缓存对象中进行操作
//创建一个新的 Request 对象,指定了要缓存的图片URL
const p = new Request('https://wen.caowj.top/static/wx.jpg')
cache.add(p)
})
}
提示:cache.add 内部会调用 fetch 方法来发起网络请求,并且 fetch 的默认方法是GET,因此cache.add 方法只能用于缓存GET请求
2. cache.addAll
使用cache.addAll可以增加多个缓存
js
cache.addAll(requests[]).then(() => {
// 所有 requests 都添加到 cache 。
});
示例:
js
if ("caches" in window) {
caches.open("cache-name").then((cache) => {
//在缓存对象中进行操作
const p = new Request('https://wen.caowj.top/static/wx.jpg')
const r = new Request('https://wen.caowj.top/static/images/userlogo.png')
cache.addAll([p, r])
})
}
Cache Storage存储状态更新:
3. cache.put
cache.put 需要手动将请求的结果存储到缓存中
js
cache.put(request, response).then(() => {
// 将 request/response 键值对添加到cache中
});
示例:
js
if ("caches" in window) {
caches.open("cache-name").then((cache) => {
fetch('https://wen.caowj.top/static/wx.jpg').then(response => {
if (response.ok) {
// 将响应存储到缓存中
cache.put('https://wen.caowj.top/static/wx.jpg', response.clone());
} else {
console.error('Network response was not ok.');
}
})
})
}
提示:cache.put虽然处理起来麻烦些,但灵活性高,可以用来缓存非GET请求。自己先通过fetch获取非GET请求结果,然后使用cache.put手动将response添加到缓存中。
4. 获取缓存
1. cache.match
通过cache.match获取缓存,返回匹配 request key 的第一个 cache
js
cache.match(request, {options}).then(response => {
// 对 response 做一些处理
});
options是一个可选对象:
ignoreSearch:Boolean值,默认为false。匹配时,是否忽略 url 的查询参数。如果该参数设置为 true ,那么 foo.com/?value=bar 中的 ?value=bar
部分就会在匹配中被忽略。
ignoreMethod:Boolean值,默认为false。是否忽略请求方法(GET/HEAD)匹配。
ignoreVary:Boolean,默认为false。是否忽略 Vary 头匹配。
示例:
js
<script>
if ("caches" in window) {
caches.open("cache-name").then((cache) => {
cache
.match("https://wen.caowj.top/static/wx.jpg")
.then((res) => res.blob()).then(res=>{
const url = URL.createObjectURL(res);
const img = document.createElement('img');
img.src = url;
document.body.appendChild(img);
})
})
}
</script>
因为缓存的是一张图片,所以使用 res.blob() 方法将响应体转换为一个 Blob 对象,将 Blob 对象使用URL.createObjectURL转换为一个对象URL,将其添加到页面的img标签上。此时页面上可以看到图片内容
2. cache.matchAll
通过cache.matchAll 获取匹配的所有请求组成的数组
js
cache.matchAll(request,{options}).then(responses => {
// 对 responses 数组做一些处理
});
options是一个可选对象,同cache.match用法。
5. 获取缓存键
返回当前 cache 实例下所有的 key。
js
cache.keys()
cache.matchAll方法本身不支持直接使用正则表达式进行匹配,但可以使用cache.keys+cache.match实现正则匹配。
例如在cache.addAll中,缓存了两个图片地址,地址都以 /static 作为前缀。
-
使用cache.keys()获取所有缓存key值
-
通过正则匹配所有以
https://wen.caowj.top/static
开头的资源 -
使用map函数,依次使用cache.match读取缓存内容,并将结果返回
-
处理匹配的响应,将结果经过处理后,添加到img标签上
js
if ("caches" in window) {
const regex = /^https:\/\/wen\.caowj\.top\/static\/.*$/;
caches.open("cache-name").then((cache) => {
cache.keys().then((requests) => {
// 过滤请求以匹配正则表达式
const filteredRequests = requests.filter((request) => regex.test(request.url));
// 使用 cache.matchAll 获取所有匹配的响应
return Promise.all(filteredRequests.map((request) => cache.match(request)));
}).then((responses) => {
// 处理匹配的响应
responses.forEach((response) => {
if (response) {
response.blob().then((blob) => {
const url = URL.createObjectURL(blob);
const img = document.createElement('img');
img.src = url;
document.body.appendChild(img);
});
}
});
})
})
}
6. 删除缓存
1. 删除匹配的缓存
js
cache.delete('https://wen.caowj.top/static/images/userlogo.png')
2. 删除缓存对象
js
caches.delete("cache-name");
结尾
本来想直接介绍PWA的使用的,但发现网上关于Cache Storage的介绍较少,并且没有相关详细使用例子的介绍,所以写了本篇文章,作为介绍PWA前的基础篇。
写作不易,点赞+收藏支持!!!