前端缓存 一般用于缓存 一些不常修改的常量数据 或 一些静态资源文件。大部分接口请求的数据都缓存在了服务端,方便统一管理缓存数据。
前端做缓存的必要性:可以缓解服务端的压力,减少带宽的占用,同时也可以提升前端的查询性能。
前端缓存可分为两大类:浏览器缓存 和 HTTP 缓存 。
浏览器缓存的分类:
浏览器往返缓存–back-forward cache(bfcache)
浏览器的 bfcache 特性
WebStorage提供两种类型的API:localStorage 和 sessionStorage。它们均继承自 Storage 类。
Storage 类的主要用途:
Storage 类型只能存储字符串,非字符串的数据在存储之前会被转为字符串。
Storage 类型有以下方法:
其中,getItem()、removeItem() 和 setItem() 方法可以直接调用,也可以通过 Storage 对象间接调用。删除数据的时候还可以使用 delete 操作符直接删除。另外,还可以使用 length 属性来判断有多少名值对儿存放在 Storage 对象中。
在使用 Storage 类型时,建议使用它的方法而不是属性来访问数据,以免某个键会意外重写该对象上已存在的成员。
对 Storage 对象进行任何修改都会在 document 对象上触发 storage 事件,这个事件的 event 对象有以下 4 个属性:
可以这样侦听 storage 事件:
EventUtil.addHandler(document, "storage", function(event){var event = EventUtil.getEvent(event);alert("当前 Storage 对象的域名是:" + event.domain);
});
上述代码中用到的 EventUtil 事件处理程序,详情请戳:js 跨浏览器事件处理程序脚本。
但是测试发现,storage 事件并未触发,怎么回事呢?
原来触发 storage 事件是有条件的,必须满足一下条件:
下面就来介绍,Storage 类的两个实例对象:localStorage 和 sessionStorage。
sessionStorage 对象是 Storage 类型的一个实例,拥有 Storage 的所有属性和方法。
sessionStorage 对象用来:存储特定的某个会话的数据。如果需要跨越会话存储数据,请选择 globalStorage 或 localStorage 对象。
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");
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"));
请参见这篇文章:Cookie 的使用
Cookie:
sessionStorage(会话存储):
localStorage(本地存储):
IndexedDB 的特点:
IndexedDB 的使用场景:
与 localstorage 相比,indexedDB 的优势在于:IndexedDB 允许储存大量数据,提供查找接口,还能建立索引。这些都是 LocalStorage 所不具备的。
就数据库类型而言,IndexedDB 不属于关系型数据库(不支持 SQL 查询语句),更接近 NoSQL 数据库。
WebSql 于 2010 年被 W3C 废弃,但主流浏览器都已经有了相关的实现。
现在官网已经停止维护 webSQL 了,转为维护 indexedDB。
WebSql 是本地数据存储方案之一。
WebSQL 更准确的说是 WebSQL DB API,它是一种操作本地数据库的网页 API 接口,通过 API 可以完成客户端数据库的操作。
当我们使用 WebSQL 的时候,可以方便地用 SQL 来对数据进行:增、删、改、查。而这些浏览器客户端,比如 Chrome 和 Safari 会用 SQLite 实现本地存储,微信就采用了 SQLite 作为本地聊天记录的存储。
WebSQL 的简单使用
WebSQL:如何在H5中存储一个本地数据库?
HTML5 的应用缓存(简称 app cache)是专门为开发离线 web 应用而设计的,确保离线时资源可用。目前,Application Cache 方案已经从 W3C 标准里移除了。
建议使用 PWA 离线缓存 方案来实现。
HTTP 缓存是通过设 置 HTTP Header 来实现的。
HTTP 缓存的设置方式有多种,按照优先级从大到小依次是:S-maxage > max-age > Expires > 预估过期时间。
HTTP 缓存分类:
强缓存指的是:只要判断缓存没有过期,则直接使用浏览器的本地缓存。
强缓存的 2 种实现方式:利用 Expires 或者 Cache-Control 这两个 HTTP Response Header 实现的,它们都用来表示资源在客户端缓存的有效期。
用 Cache-Control 实现 强缓存 的流程如下:
协商缓存指的是:与服务端协商之后,通过协商结果来判断是否使用本地缓存。
协商缓存的 2 种实现方式:
这 2 种协商缓存的 实现流程 如下:
按缓存位置可以将浏览器缓存分为以下 4 种,按照优先级从大到小依次是:Service Worker > Memory Cache > Disk Cache > Push Cache。
浏览器会依次查找这 4 个缓存,只有当所有的缓存都没有命中的时候,才会去请求网络。
service Worker 的缓存与浏览器其他内建的缓存机制不同,它可以让我们自由控制缓存
哪些文件、如何匹配缓存、如何读取缓存,并且缓存是持续性的。
当 Service Worker 没有命中缓存的时候,我们需要去调⽤ fetch 函数获取数据。也就是说,如果我们没有在 Service Worker 命中缓存的话,会根据缓存查找优先级去查 找数据。但是不管我们是从 Memory Cache 中还是从网络请求中获取的数据,浏览器都会显示我们是从 Service Worker 中获取的内容。
Memory Cache 也就是内存中的缓存,读取内存中的数据肯定比磁盘快。但是内存缓存虽
然读取高效,可是缓存持续性很短,会随着进程的释放⽽释放。 ⼀旦我们关闭 Tab 页面,内存中的缓存也就被释放了。
当我们访问过页面以后,再次刷新页面,可以发现很多数据都来自于内存缓存。
Disk Cache 也就是存储在硬盘中的缓存,读取速度慢点,但是什么都能存储到磁盘中, 比之 Memory Cache 胜在容量和存储时效性上。
在所有浏览器缓存中, Disk Cache 覆盖⾯基本是最⼤的。它会根据 HTTP Herder 中的字段判断哪些资源需要缓存,哪些资源可以不请求直接使用,哪些资源已经过期需要重新请求。并且即使在跨站点的情况下,相同地址的资源⼀旦被硬盘缓存下来,就不会再次去请求数据。
Push Cache 是 HTTP/2 中的内容,当以上三种缓存都没有命中时,它才会被使⽤。并且缓存时间也很短暂,只在会话(Session )中存在,⼀旦会话结束就被释放。
【参考文章】
浏览器缓存原理总结
一文读懂http缓存(超详细)
http缓存详解( 直接看图,超易懂🤗 )
前端浏览器缓存知识梳理
设计一个无懈可击的浏览器缓存方案:关于思路,细节,ServiceWorker,以及HTTP/2
「面试题」简述浏览器缓存是如何控制的
理解 Web 缓存
浏览器缓存看这一篇就够了
彻底理解浏览器的缓存机制
彻底弄懂前端缓存
浏览器数据库 IndexedDB 入门教程