除了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...

相关推荐
夜郎king17 分钟前
HTML5 SVG 实现日出日落动画与实时天气可视化
前端·html5·svg 日出日落
夏幻灵1 小时前
HTML5里最常用的十大标签
前端·html·html5
Mr Xu_2 小时前
Vue 3 中 watch 的使用详解:监听响应式数据变化的利器
前端·javascript·vue.js
未来龙皇小蓝2 小时前
RBAC前端架构-01:项目初始化
前端·架构
程序员agions2 小时前
2026年,微前端终于“死“了
前端·状态模式
万岳科技系统开发2 小时前
食堂采购系统源码库存扣减算法与并发控制实现详解
java·前端·数据库·算法
程序员猫哥_2 小时前
HTML 生成网页工具推荐:从手写代码到 AI 自动生成网页的进化路径
前端·人工智能·html
龙飞052 小时前
Systemd -systemctl - journalctl 速查表:服务管理 + 日志排障
linux·运维·前端·chrome·systemctl·journalctl
我爱加班、、2 小时前
Websocket能携带token过去后端吗
前端·后端·websocket
AAA阿giao2 小时前
从零拆解一个 React + TypeScript 的 TodoList:模块化、数据流与工程实践
前端·react.js·ui·typescript·前端框架