前端缓存汇总
admin
2024-02-09 15:48:46

目录

  • 前言
  • 一、浏览器缓存
    • 0、bfcache
    • 1、WebStorage
      • (1)、sessionStorage 对象
      • (2)、localStorage 对象
    • 2、Cookie
      • (1)、cookie 与 sessionStorage、localStorage 的对比
    • 3、IndexedDB
    • 4、WebSql
    • 5、H5 webapp 的离线缓存
  • 二、HTTP 缓存
    • 1、强缓存
    • 2、协商缓存
  • 三、按缓存位置区分浏览器缓存
    • 1、Service Worker
    • 2、Memory Cache
    • 3、Disk Cache
    • 4、Push Cache


前言

前端缓存 一般用于缓存 一些不常修改的常量数据一些静态资源文件。大部分接口请求的数据都缓存在了服务端,方便统一管理缓存数据。

前端做缓存的必要性:可以缓解服务端的压力,减少带宽的占用,同时也可以提升前端的查询性能。

前端缓存可分为两大类:浏览器缓存HTTP 缓存


一、浏览器缓存

浏览器缓存的分类:

  • 默认存储:往返缓存 BFCache
  • 本地存储(客户端存储):
    • Cookie
    • WebStorage
      • sessionStorage(会话存储)
      • localStorage(本地存储)
    • IndexedDB
    • WebSql
    • H5 webapp 的离线缓存
      • PWA

0、bfcache

浏览器往返缓存–back-forward cache(bfcache)
浏览器的 bfcache 特性

1、WebStorage

WebStorage提供两种类型的API:localStorage 和 sessionStorage。它们均继承自 Storage 类。

Storage 类的主要用途:

  • 提供一种在 cookie 之外存储会话数据的途径;
  • 提供一种可以存储大量的跨会话数据的机制(不会产生跨域)。
  • 与操作 cookie 中的数据不同,由于 Storage 类型的数据不会产生跨域,所以操作它里面的数据的时候不必开启本地服务器(Wampserver)。

Storage 类型只能存储字符串,非字符串的数据在存储之前会被转为字符串。

Storage 类型有以下方法:

  • clear():删除所有值。
  • getItem(name):根据指定的名字 name 获取对应的值。
  • key(index):获得 index 位置处的值的名字。
  • removeItem(name):删除由 name 指定的名值对儿。
  • setItem(name, value):为指定的 name 设置一个对应的值。

其中,getItem()、removeItem() 和 setItem() 方法可以直接调用,也可以通过 Storage 对象间接调用。删除数据的时候还可以使用 delete 操作符直接删除。另外,还可以使用 length 属性来判断有多少名值对儿存放在 Storage 对象中。

在使用 Storage 类型时,建议使用它的方法而不是属性来访问数据,以免某个键会意外重写该对象上已存在的成员

对 Storage 对象进行任何修改都会在 document 对象上触发 storage 事件,这个事件的 event 对象有以下 4 个属性:

  • domain:发生变化的存储空间的域名。
  • key:设置或删除的键名。
  • newValue:如果是设置值,则是新值;如果是删除键,则是 null。
  • oldValue:键被更改之前的值。

可以这样侦听 storage 事件:

EventUtil.addHandler(document, "storage", function(event){var event = EventUtil.getEvent(event);alert("当前 Storage 对象的域名是:" + event.domain);
});


上述代码中用到的 EventUtil 事件处理程序,详情请戳:js 跨浏览器事件处理程序脚本

但是测试发现,storage 事件并未触发,怎么回事呢?

原来触发 storage 事件是有条件的,必须满足一下条件:

  • 同一浏览器打开了两个同源页面;
  • 其中一个页面修改了localStorage;
  • 另一个网页注册了这个事件。

下面就来介绍,Storage 类的两个实例对象:localStorage 和 sessionStorage。

(1)、sessionStorage 对象

sessionStorage 对象是 Storage 类型的一个实例,拥有 Storage 的所有属性和方法。

sessionStorage 对象用来:存储特定的某个会话的数据。如果需要跨越会话存储数据,请选择 globalStorage 或 localStorage 对象。

sessionStorage 对象的特点:

  • 页面刷新不会影响 sessionStorage 对象中的数据;除 IE 之外,其他浏览器即使崩溃了,重启后也不会影响 sessionStorage 对象中的数据。
  • 因为 sessionStorage 对象绑定于某个服务器会话,所以当文件在本地运行时 sessionStorage 是不可用的。
  • 存储在 sessionStorage 对象中的数据只能由最初给该对象存储的页面能够访问到,所以对多页面应用有限制。

操作 sessionStorage 对象里存储的数据:

// 存储数据
sessionStorage.name02 = "Caocao";
sessionStorage.setItem("name01", "Zhangfei");
// 获取数据
console.log(sessionStorage.name01); // Caocao
console.log(sessionStorage.getItem("name02")); // Zhangfei
// 删除数据
delete sessionStorage.name01;
sessionStorage.removeItem("name02");

(2)、localStorage 对象

localStorage 对象是 Storage 类型的一个实例,拥有 Storage 的所有属性和方法。

localStorage 对象用来:持久保存客户端的数据(数据保留到通过 JavaScript 删除或者是用户清除浏览器缓存)。

localStorage 对象的特点:

  • 必须遵从同源策略(同协议、同域名、同端口),否则会跨域。

操作 localStorage 对象中的数据:

// 存储数据
localStorage.name01 = "Liuibang";
localStorage.setItem("name02", "Zhangliang");
// 获取数据
console.log(localStorage.name01); // Liuibang
console.log(localStorage.getItem("name02")); // Zhangliang
// 删除数据
delete localStorage.name01;
localStorage.removeItem("name02");

localStorage 同时存取储多条数据:

// 存
const data = {a: 111,b: "333",c: false,
};
localStorage.setItem("data", JSON.stringify(data));// 取
const data = JSON.parse(localStorage.getItem("data"));

2、Cookie

请参见这篇文章:Cookie 的使用

(1)、cookie 与 sessionStorage、localStorage 的对比

Cookie:

  • 用来存储客户端的 HTTP 状态信息。
  • 同一个域名下的 cookie 是共享的。不利于 http 性能的提升,而且不同域名间会产生跨域。
  • 数量受限,大小受限。不同的浏览器对 cookie 都有各自的数量限制,且每个 cookie 只能存储 4KB 大小的数据。
  • 可以设置有效期。关闭浏览器后,没有设置有效期的 cookie 会被清掉,设置了有效期的 cookie 会继续生效,直到过期时自动清掉。

sessionStorage(会话存储):

  • 用于临时保存同一窗口(或标签页)的数据。在关闭窗口后这些数据会自动删除。
  • 只能存储字符串。
  • 不会产生跨域。
  • 同步存储。
  • 大小受限,最多只能存储 5M 。

localStorage(本地存储):

  • 用来持久保存客户端的数据。只要不人为删除数据会一直在。
  • 只能存储字符串。
  • 不会产生跨域。
  • 同步存储。
  • 大小受限,最多只能存储 5M 。

3、IndexedDB

IndexedDB 的特点:

  • 键值对存储:在对象仓库中,数据以“键值对”的形式保存,每一个数据都有对应的键名,键名是独一无二的,不能有重复,否则会抛出一个错误。
  • 支持二进制储存:可存储字符串、二进制数据(ArrayBuffer 对象和 Blob 对象)。
  • 支持异步存储:。
  • 储存空间大:不同浏览器的上限不同。
  • 支持事务:IndexedDB 支持事务,这意味着一系列操作步骤之中,只要有一步失败,整个事务就都取消,数据库回滚到事务发生之前的状态,不存在只改写一部分数据的情况。
  • 同域限制: IndexedDB 受到同源限制,每一个数据库对应创建它的域名。网页只能访问自身域名下的数据库,而不能访问跨域的数据库。
  • 览器兼容性不好。

IndexedDB 的使用场景:

  • 数据超过了 5M,建议使用 IndexedDB 存储在本地。
  • 数据在 5M 以内,建议使用 localStorage 存储在本地。

与 localstorage 相比,indexedDB 的优势在于:IndexedDB 允许储存大量数据,提供查找接口,还能建立索引。这些都是 LocalStorage 所不具备的。

就数据库类型而言,IndexedDB 不属于关系型数据库(不支持 SQL 查询语句),更接近 NoSQL 数据库。

4、WebSql

WebSql 于 2010 年被 W3C 废弃,但主流浏览器都已经有了相关的实现。
现在官网已经停止维护 webSQL 了,转为维护 indexedDB。

WebSql 是本地数据存储方案之一。

WebSQL 更准确的说是 WebSQL DB API,它是一种操作本地数据库的网页 API 接口,通过 API 可以完成客户端数据库的操作。

当我们使用 WebSQL 的时候,可以方便地用 SQL 来对数据进行:增、删、改、查。而这些浏览器客户端,比如 Chrome 和 Safari 会用 SQLite 实现本地存储,微信就采用了 SQLite 作为本地聊天记录的存储。

WebSQL 的简单使用
WebSQL:如何在H5中存储一个本地数据库?

5、H5 webapp 的离线缓存

HTML5 的应用缓存(简称 app cache)是专门为开发离线 web 应用而设计的,确保离线时资源可用。目前,Application Cache 方案已经从 W3C 标准里移除了。

建议使用 PWA 离线缓存 方案来实现。


二、HTTP 缓存

HTTP 缓存是通过设 置 HTTP Header 来实现的。

HTTP 缓存的设置方式有多种,按照优先级从大到小依次是:S-maxage > max-age > Expires > 预估过期时间

HTTP 缓存分类:

  • 强缓存:在缓存期间不需要请求。
    • Pragma
    • Cache-Control
    • Expires
  • 协商缓存:如果缓存过期了,就需要发起请求验证资源是否有更新。当浏览器发起请求验证资源时,如果资源没有做改变,那么服务端就会返回 304 状态 码,并且更新浏览器缓存有效期。
    • ETag/If-Not-Match
    • Last-Modified/If-Modified-Since

1、强缓存

强缓存指的是:只要判断缓存没有过期,则直接使用浏览器的本地缓存。

强缓存的 2 种实现方式:利用 Expires 或者 Cache-Control 这两个 HTTP Response Header 实现的,它们都用来表示资源在客户端缓存的有效期。

  • Expires 属性是一个绝对时间。
  • Cache-Control 属性是一个相对时间,即一个过期时间大小,与协商缓存一样。可以更加准确地判断文件内容是否被修改,避免由于时间篡改导致的不可靠问题。

用 Cache-Control 实现 强缓存 的流程如下:

  • 当浏览器第一次请求访问服务器资源时,服务器会在返回这个资源的同时,在 Response 头部加上 Cache-Control,Cache-Control 中设置了过期时间大小;
  • 浏览器再次请求访问服务器中的该资源时,会先通过请求资源的时间与 Cache-Control 中设置的过期时间大小,来计算出该资源是否过期,如果没有,则使用该缓存,否则请求服务器;
  • 服务器再次收到请求后,会再次更新 Response 头部的 Cache-Control。

2、协商缓存

协商缓存指的是:与服务端协商之后,通过协商结果来判断是否使用本地缓存。

协商缓存的 2 种实现方式:

  • 可以基于请求头部中的 If-Modified-Since 字段与返回头部中的 Last-Modified 字段实现——基于时间实现
  • 也可以基于请求头部中的 If-None-Match 字段与返回头部中的 ETag 字段来实现——基于唯一标识实现——可以更加准确地判断文件内容是否被修改,避免由于时间篡改导致的不可靠问题。

这 2 种协商缓存的 实现流程 如下:

  • 当浏览器第一次请求访问服务器资源时,服务器会在返回这个资源的同时,在 Response 头部加上 ETag 唯一标识,这个唯一标识的值是根据当前请求的资源生成的;
  • 当浏览器再次请求访问服务器中的该资源时,会在 Request 头部加上 If-None-Match 字段,该字段的值就是 Response 头部加上 ETag 唯一标识;
  • 服务器再次收到请求后,会根据请求中的 If-None-Match 值与当前请求的资源生成的唯一标识进行比较,如果值相等,则返回 304 Not Modified,如果不相等,则在 Response 头部加上新的 ETag 唯一标识,并返回资源;
  • 如果浏览器收到 304 的请求响应状态码,则会从本地缓存中加载资源,否则更新资源。

三、按缓存位置区分浏览器缓存

按缓存位置可以将浏览器缓存分为以下 4 种,按照优先级从大到小依次是:Service Worker > Memory Cache > Disk Cache > Push Cache

浏览器会依次查找这 4 个缓存,只有当所有的缓存都没有命中的时候,才会去请求网络。

1、Service Worker

service Worker 的缓存与浏览器其他内建的缓存机制不同,它可以让我们自由控制缓存
哪些文件、如何匹配缓存、如何读取缓存,并且缓存是持续性的。

当 Service Worker 没有命中缓存的时候,我们需要去调⽤ fetch 函数获取数据。也就是说,如果我们没有在 Service Worker 命中缓存的话,会根据缓存查找优先级去查 找数据。但是不管我们是从 Memory Cache 中还是从网络请求中获取的数据,浏览器都会显示我们是从 Service Worker 中获取的内容。

2、Memory Cache

Memory Cache 也就是内存中的缓存,读取内存中的数据肯定比磁盘快。但是内存缓存虽
然读取高效,可是缓存持续性很短,会随着进程的释放⽽释放。 ⼀旦我们关闭 Tab 页面,内存中的缓存也就被释放了。

当我们访问过页面以后,再次刷新页面,可以发现很多数据都来自于内存缓存。

3、Disk Cache

Disk Cache 也就是存储在硬盘中的缓存,读取速度慢点,但是什么都能存储到磁盘中, 比之 Memory Cache 胜在容量和存储时效性上。

在所有浏览器缓存中, Disk Cache 覆盖⾯基本是最⼤的。它会根据 HTTP Herder 中的字段判断哪些资源需要缓存,哪些资源可以不请求直接使用,哪些资源已经过期需要重新请求。并且即使在跨站点的情况下,相同地址的资源⼀旦被硬盘缓存下来,就不会再次去请求数据。

4、Push Cache

Push Cache 是 HTTP/2 中的内容,当以上三种缓存都没有命中时,它才会被使⽤。并且缓存时间也很短暂,只在会话(Session )中存在,⼀旦会话结束就被释放。




【参考文章】
浏览器缓存原理总结
一文读懂http缓存(超详细)
http缓存详解( 直接看图,超易懂🤗 )
前端浏览器缓存知识梳理

设计一个无懈可击的浏览器缓存方案:关于思路,细节,ServiceWorker,以及HTTP/2
「面试题」简述浏览器缓存是如何控制的
理解 Web 缓存
浏览器缓存看这一篇就够了
彻底理解浏览器的缓存机制
彻底弄懂前端缓存

浏览器数据库 IndexedDB 入门教程

相关内容

热门资讯

赤水性价比粮食酒推荐:2025... 赤水性价比粮食酒推荐:2025年酱香酒选购全攻略 一、开篇背景与市场痛点 2025年的赤水河流域酒类...
非白酒板块11月19日跌0.3... 证券之星消息,11月19日非白酒板块较上一交易日下跌0.33%,*ST椰岛领跌。当日上证指数报收于3...
以运河文化赋能产业发展|古贝春... 11月17日至19日,以“新质开新局,聚力创未来”为主题的2025年第六届中国白酒黄淮核心产区高质量...
深夜小酌的灵魂搭档:油炝脆骨,... 油炝脆骨是一道充满锅气与烟火气息的家常菜,以其爽脆的口感和浓郁的香辣风味深受许多人喜爱。这道菜的制作...
初中毕业新征程:为什么西点烘焙... 站在初中毕业的人生路口,许多女孩都在思考:哪条路能通往一个既美好又独立的未来?如果有一条道路,能将女...