除了localStorage、sessionStorage,了解Cache Storage吗?

前言

Cache Storage 是 Web 开发中一个非常强大的工具,主要用于缓存网络资源,从而提高页面二次加载速度。如果对页面首次加载速度优化感兴趣的,可参考我的另一篇文章:[前端进阶] 首屏优化知识梳理

1. 简介

Cache Storage 用于存储和管理HTTP请求和响应。以请求URL作为key,接口返回的数据作为value。

特点:

  1. 它与HTTP缓存完全隔离,可以减少带宽,提供离线能力。

  2. 它是一个异步化的存储方式。

存储空间:

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 作为前缀。

  1. 使用cache.keys()获取所有缓存key值

  2. 通过正则匹配所有以https://wen.caowj.top/static开头的资源

  3. 使用map函数,依次使用cache.match读取缓存内容,并将结果返回

  4. 处理匹配的响应,将结果经过处理后,添加到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前的基础篇。

写作不易,点赞+收藏支持!!!

参考链接:juejin.cn/post/684490...

相关推荐
开心工作室_kaic37 分钟前
ssm161基于web的资源共享平台的共享与开发+jsp(论文+源码)_kaic
java·开发语言·前端
刚刚好ā37 分钟前
js作用域超全介绍--全局作用域、局部作用、块级作用域
前端·javascript·vue.js·vue
沉默璇年2 小时前
react中useMemo的使用场景
前端·react.js·前端框架
yqcoder2 小时前
reactflow 中 useNodesState 模块作用
开发语言·前端·javascript
2401_882727572 小时前
BY组态-低代码web可视化组件
前端·后端·物联网·低代码·数学建模·前端框架
SoaringHeart2 小时前
Flutter进阶:基于 MLKit 的 OCR 文字识别
前端·flutter
会发光的猪。3 小时前
css使用弹性盒,让每个子元素平均等分父元素的4/1大小
前端·javascript·vue.js
天下代码客3 小时前
【vue】vue中.sync修饰符如何使用--详细代码对比
前端·javascript·vue.js
猫爪笔记3 小时前
前端:HTML (学习笔记)【1】
前端·笔记·学习·html
前端李易安4 小时前
Webpack 热更新(HMR)详解:原理与实现
前端·webpack·node.js