前言
浏览器缓存对开发者来说一直都是一个有爱又恨的存在,一方面帮助开发者提升用户体验,另一方面有时会抽风,读取缓存展示错误的内容,因此,希望对浏览器缓存做一个总结,避免开发时因为缓存机制而过多耗费时间。接下来,就进入浏览器缓存的世界
什么是缓存
缓存是指一个资源存在于服务器和客户端之间的副本,缓存会根据请求保存输出内容的副本,当下一个请求进来的时候,如果是相同的URL,缓存会根据缓存机制决定是直接使用副本响应还是向源服务器重新请求,当你访问一个网站时,打开调试面板,你会发现几乎静态资源请求都是从缓存中读取出来的,如图:
为什么要缓存
不用缓存可以吗?当然可以,至于后果是什么?试了就知道。用了缓存之后,会有什么好处:
浏览器缓存
前菜结束上硬菜,本篇主角浏览器缓存,浏览器缓存是众多web缓存分类中的一种,主要分为:
Memory Cache
Memory Cache指的是内存中的缓存,它有如下几个特点:
来看一个例子:
第一张图是第一次打开网页时截取的,圈圈标记的图片时存放在Disk Cache里面的,第二张图时网页刷新时截取的,圈圈标记的图片是存放在Memory Cache中的,同样的图片两次为什么是从不同的缓存中读取的呢?因为Memory Cache进程关闭时就会清空,但是第二次刷新的时候,第一次浏览器解析图片文件进入Memory Cache,第二次刷新时由于Memory Cache是浏览器请求时最先去尝试命中的缓存,因此会直接去从Memory Cache中取Service Worker Cache
Service Worker是一种独立于主线程之外的JAVAScript线程,不会对当前程序的执行线程造成堵塞,通过Service Worker我们可以自由控制缓存哪些文件、如何匹配缓存、如何读取缓存,通过Service Worker实现的缓存称为Service Worker Cache,如果你对Service Worker有更深入了解的兴趣,可以去看看我之前的一篇博客:传送门
HTTP Cache
HTTP Cache是我们日常开发中接触最多也是最为熟悉的缓存,HTTP Cache通常可以分为强缓存和协商缓存,缓存策略都是通过HTTP Header来实现的,强缓存的优先级高于协商缓存,在命中强缓存失败的情况下才会去命中协商缓存
强缓存
强缓存主要通过设置HTTP Header Expires和Cache-Control两个字段控制,当请求发出时。浏览器会根据上一次请求时记录的Expires和Cache-Control来判断是否命中强缓存,若命中则直接从强缓存中取资源,不会再向服务发送请求,当命中强缓存时,HTTP状态码返回200,且Size显示from disk cache,如图所示:
Expires
Expires缓存过期时间,值为一个时间戳。如图:
当我们两次向同一个服务器请求资源时,第二次请求时,浏览器会先对比Expires时间戳和本地时间,如果本地时间小于Expires时间戳就会去缓存中取资源,但是这样存在一个问题,Expires依赖客户端时间,如果客户端时间和服务端时间不一致时,就会产生问题,Expires是HTTP1.0标准下的字段,考虑到这个问题,因此在HTTP1.1标准下新增了Cache-Control字段Cache-Control
Cache-Control字段是Expires字段的完全替代方案,它做Expires字段能做的所有事,还有Expires字段不能做的事情,当前还在用Expires字段的目的只是向下兼容,Cache-Control字段包含多个指令,这里介绍几个最常用的:
协商缓存
协商缓存就是强制缓存失效后,浏览器浏览器携带缓存标识向服务发起请求,由服务器更具缓存标识决定是否返回缓存,主要有两种情况:
接下来介绍和协商缓存相关的头部字段:
Last-Modified/If-Modified-since
Last-Modified指明资源最终修改的时间,值为一个时间戳,如图:
当缓存要对已缓存的文档进行再验证时,请求头中就会包含一个If-Modified-since首部,其携带有此资源最后修改的时间戳,如图:
如果在此期间内容被修改,最后的修改日期就会有所不同,源服务器就会返回新的内容重新响应,否则就会返回304,重定向到浏览器缓存。
由于这些缺陷HTTP1.1出现了Etag/If-None-Match
Etag/If-None-Match
ETag能告知客户端实体标识,它是一种可将资源以字符串形式做唯一标识的方式。服务器会为每份资源分配对应的ETag值,当资源更新ETag值也会更新,如图:
当我们下次请求时,请求头里会带上一个If-None-Match字符串提供服务端对比,如图:
如果服务器上的标签已经发生了变化,服务器会在一个200响应中返回新的内容以及新的ETag,否则返回304重定向到缓存HTTP缓存决策
此图源自google,清楚展示了HTTP Cache决策的过程,对上面介绍的缓存过程做了一个完美的总结Push Cache
Push Cache指HTTP2在server push阶段存在的缓存,是HTTP2 session的一部分,不是一个持久化的缓存,当session结束时,缓存也会随之结束,不同的页面只要共享了同一个HTTP2连接,那么它们就可以共享同一个Push Cache,如果你对Push Cache还有更多的兴趣,这里提供三篇文章供你阅读:
总结
此篇文章记录总结了浏览器缓存相关的一些知识点,是个人最近对缓存知识的一个总结,希望对大家也能有所帮助。
如果有错误或不严谨的地方,欢迎批评指正,如果喜欢,欢迎点赞