浏览器缓存相关知识点

从缓存位置分为四种,并且有各自的优先级,按优先级从高到低排序分别是:

1、Service Worker
2、Memory Cache
3、Dish Cache
4、Push Cache

Service Worker

Service Worker 是运行在浏览器背后的独立线程,涉及到请求拦截,所以必须使用 HTTPS 协议来保障安全。

它可以让我们自由控制缓存哪些文件、如何匹配缓存、如何读取缓存,并且缓存是持续性的。

Service Worker 实现缓存功能一般分为三个步骤:

1、首先需要先注册 Service Worker。
2、然后监听到 install事件以后就可以缓存需要的文件。
3、那么在下次用户访问的时候就可以通过拦截请求的方式查询是否存在缓存,存在缓存的话就可以直接读取缓存文件,否则就去请求数据。

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

功能:比如离线缓存、消息推送和网络代理等功能。其中的离线缓存就是 Service Worker Cache。

Memory Cache

指的是内存中的缓存,主要包含的是当前页面中已经抓取到的资源。
读取内存中的数据肯定比磁盘快,内存缓存虽然读取高效,但是缓存持续性很短,一旦我们关闭Tab页面,内存中的缓存也就被释放了。

Disk Memory

指的是存储在硬盘中的缓存,从存取效率上讲是比内存缓存慢的,但是他的优势在于存储容量和存储时长。
浏览器会把大文件丢进硬盘缓存中

Push Cache

Push Cache(推送缓存)是 HTTP/2 中的内容,当以上三种缓存都没有命中时,它才会被使用。它只在会话(Session)中存在,并且缓存时间也很短暂,一旦会话结束就被释放,在Chrome浏览器中只有5分钟左右。

如果以上四种缓存都没有命中的话,那么只能发起请求来获取资源了。通常浏览器缓存策略分为两种:强缓存和协商缓存,并且缓存策略都是通过设置 HTTP Header 来实现的。

从缓存方式分为两种,并且有各自的优先级,按优先级从高到低排序分别是:

1、强缓存
2、协商缓存

强缓存

检查强缓存是不需要发送HTTP请求的,直接从缓存中读取资源,在Chrome控制台的Network选项中可以看到该请求返回200的状态码,并且Size显示from disk cache或者是from memory cache。

强缓存可以通过设置两种HTTP Header实现。

  • Expires(HTTP/1.0)
  • Cache-Control(HTTP/1.1)

Expires

Expires即为缓存过期时间,指定资源到期的事件,存在于服务器返回的响应头中,告诉浏览器在这个过期时间之内可以直接从缓存中获取数据,而不需要再次发送请求。

Expires是HTTP/1.0的产物,受限于本地时间,如果修改了本地时间,可能会造成缓存失效。(即服务器的时间和浏览器的时间可能并不一致)

Cache-Control

Cache-Control是采用过期时长来控制缓存,对应的选项有max-age。

Expires和Cache-Control两者对比

区别就在于 Expires是HTTP/1.0的产物,Cache-Control是HTTP/1.1的产物,
两者同时存在的话,Cache-Control优先级高于Expires;

强缓存判断是否缓存的依据来自于是否超出某个时间或者某个时间段,而不关心服务器端文件是否已经更新,这可能会导致加载文件不是服务器端最新的内容,那我们如何获知服务器端内容是否已经发生了更新呢?此时我们需要用到协商缓存策略。

协商缓存

协商缓存就是强制缓存失效后(强缓存时间到期),浏览器携带缓存标识(tag)向服务器发起请求,由服务器根据缓存标识决定是否使用缓存的过程,tag主要有以下两种情况:

  • Last-Modified
  • ETag

Last-Modified

Last-Modified为最后修改时间。在浏览器第一次给服务器发送请求的时候,服务器会在响应头中加上这个字段。
浏览器接收后,如果再次发送请求,会在请求头中携带If-Modified-Since字段,这个字段的值就是服务器传来的资源最后修改时间。
服务器拿到请求头的If-Modified-Since字段,会和服务器中该资源的最后修改事件做对比:

如果请求头的值小于最后修改时间,说明资源更新,返回新的资源,跟常规的HTTP请求响应一样。

否则返回304状态码和Not Modified,告诉浏览器直接使用缓存。

使用Last-Modified的弊端:

因为Last-Modified 只能以秒计时,如果在不可感知的时间内修改完成文件,那么服务端会认为资源还是命中了,不会返回已被修改过的资源。根据文件修改时间来决定是否缓存尚有不足,能否可以直接根据文件内容是否修改来决定缓存策略?所以在 HTTP/1.1 出现了 ETag 和If-None-Match。

Etag

Etag是服务器响应请求时,返回当前资源文件的一个唯一标识(由服务器生成),只要资源有变化,Etag就会重新生成。

浏览器在下一次加载资源向服务器发送请求时,会将上一次返回的Etag值放到请求头的If-None-Match字段里,服务器需要比较客户端传来的If-None-Match跟自己服务器上该资源的Etag是否一致,就可以判断资源相对于客户端而言是否已经被修改过了。有以下两种情况:

如果ETag是一致的,则直接返回304,通知客户端直接使用本地缓存即可。
如果服务器发现ETag匹配不上,那么直接以常规请求形式将新的资源(包括了新的ETag)发给客户端。

Last-Modified和Etag对比

  • 在精确度上,Etag要优于Last-Modified。
  • 在性能上,Etag要逊于Last-Modified。
  • 在优先级上,服务器校验优先考虑Etag。

总结

强制缓存优先于协商缓存进行,若强制缓存(Expires和Cache-Control)生效则直接使用缓存,若不生效则进行协商缓存(Last-Modified / If-Modified-Since和Etag / If-None-Match),协商缓存由服务器决定是否使用缓存,若协商缓存失效,那么代表该请求的缓存失效,返回200,重新返回资源和缓存标识,再存入浏览器缓存中;生效则返回304,继续使用缓存。
缓存机制

用户行为对浏览器缓存的影响

所谓用户行为对浏览器缓存的影响,指的就是用户在浏览器如何操作时,会触发怎样的缓存策略。主要有 3 种:

1、打开网页,地址栏输入地址: 查找 disk cache中是否有匹配。如有则使用;如没有则发送网络请求。
2、普通刷新 (F5):因为 TAB 并没有关闭,因此 memory cache是可用的,会被优先使用(如果匹配的话)。其次才是 disk cache。
3、强制刷新 (Ctrl + F5):浏览器不使用缓存,因此发送的请求头部均带有 Cache-control: no-cache(为了兼容,还带了 Pragma: no-cache),服务器直接返回 200 和最新内容。

原文链接:
https://juejin.im/post/6847902216431337479

你可能感兴趣的:(Web前端)