一、前言
缓存是前端性能优化最简单高效的一种方式/一个优秀的缓存 策略可以缩短网页请求资源的距离,减少延迟,并因为缓存文件可以重复利用,还可以减少带宽,降低网络负荷。对于一个数据请求来说,可以分为 发起请求、后端处理、浏览器响应三个步骤。浏览器缓存可以帮助我们在第一和第三的步骤中优化性能。比如说直接使用缓存不发送请求,或者发起了请求但后端数据和前端一致,那么就没有必要在将数据回传,减少了响应数据
缓存位置
从缓存位置上来说分为四种,并且各自有优先级,当依次查找缓存并且都没有命中时,才会去请求网络。按照优先级从高到低排序如下
- Service Worker
- Memory Cache
- Disk Cache
- Push Cache
1、Service Worker
Service Worker 是运行在浏览器背后的独立线程,即让JS 运行在主线程之外,由于它脱离了浏览器的窗体,因此无法直接访问到Dom。但仍可以帮我们完成很多功能。 一般可以用来实现缓存功能。使用Service Worker的话,传输协议必须为Https。因为Service Worker 中涉及到请求拦截,所以必须使用HTTPS来保障安全。Service的缓存与浏览器其它内建缓存机制不同。它可以t让我们自由的控制缓存哪些文件、如何匹配缓存、如何读取缓存、并且缓存时持续性的。
Service Worker 实现缓存功能一般分为三个步骤:首先需要先注册Service Worker,然后监听到install 事件后就可以缓存需要的文件,那么在用户下次访问时就可以通过拦截请求的方式来查询缓存是否存在,存在的话就直接读取缓存,否则的话就去请求数据
当serviceworker 没有命中缓存时,我需要去调取fetch 函数获取数据。也就是说,如果,当我们在service worker 中没有命中缓存的话,会根据缓存查找优先级逐级去查找数据。但不管我们是从Memory Cache 还是从网络请求中获取数据,浏览器都会显示我们是从Service Worker 中获取的。
2.Memory Cache
Memory Cache 也就是内存中的缓存,主要包含的是当前页面中已经抓取到的资源,例如页面上已经下载的样式、脚本、图片等。内存中缓存的数据读取高效但缓存的持续性短,会随着进程的释放而释放。一旦我们关闭tab页,内存中的缓存也被释放了。
既然内存缓存如此高效,为何不将所有数据都放在内存缓存中呢?
因为相对于磁盘容量,内存要小的多,系统使用内存要精打细算,所以能让我们使用的不多。
当我们访问过页面以后,再次刷新页面,可以发现很多数据都来自于内存缓存

内存缓存中有一块重要的缓存资源是preloader相关指令如()下载的资源。众所周知preloader的相关指令是页面优化的常规手段之一,它可以一边解析js/css 文件一边网络请求下载资源。
注意点:内存缓存在缓存资源时并不关心返回资源的HTTP缓存头Cache-Control是什么值,同时资源的匹配也并非仅仅是对URL做匹配,还可能会对Content-Type,CORS等其他特征做校验
3.Disk Cache
Disk Cache 也就是存储在硬盘中的缓存,虽然读取速度慢,但是什么都能存储到磁盘中,在存储容量和时效性上都要超过Memory Cache
在所有浏览器缓存中,Disk Cache 覆盖面基本上是最大的。它会根据HTTP Herder 中的字段判断哪些资源需要缓存,哪些资源可以不请求直接使用,哪些资源已经过期要重新请求。并且即使在跨站点的情况下,相同地址的资源一旦被硬盘缓存下来,就不会再次去请求数据。绝大部分的缓存都来自Disk,Cache,关于HTTP协议头中的缓存字段,以后在详细介绍。
浏览器会将哪些文件丢进内存中?哪些丢进硬盘中? 1.对于大文件来说,大概率是不存储在内存中,反之优先 2.当系统内存使用率高的时候,文件优先存到硬盘
4.Push Cache
Push Cash(推送缓存)是HTTP/2中的内容,当以上三种缓存都没有命中时,它才会被使用。<它只在会话(Session)中存在,一旦会话结束就会被释放,并且缓存时间也很短暂,在chrome浏览器中只有5分钟左右,同时它也并非严格执行HTTP头中的缓存指令。 Push Cache在国内能够查到的资料很少,也是因为HTTP/2在国内不够普及。
1.所有资源都能被推送,并且能够被缓存,但是Edge和Safari浏览器相对支持较差。
2.可以推送no-cache和no-store的资源
3.一旦连接被关闭,Push Cache就被释放
4.多个页面可以使用一个HTTP/2的链接,也就是可以使用一个Push Cache。这主要还是依赖浏览器的实现而定,出于对性能的考虑,有的浏览器会对相同域名但不同的tab的标签使用同一个HTTP链接。
5.Push Cache中的缓存只能被使用一次
6.浏览器可以拒绝接受已经存在的资源推送
7.你可以给其他域名推送资源
若以上四种缓存都没有命中,只能发起请求来获取资源了。
那么为了性能上的考虑,大部分的接口都应该选择好缓存策略,通常浏览器缓存策略分为两种:强缓存和协商缓存,并且缓存策略都是通过设置 HTTP Header 来实现的。