Open su-Pro opened 4 years ago
浏览器缓存机制有四个方面,获取资源时请求的优先级依次排列如下:
memory cache 是浏览器默认的缓存,形如from memory cache,service worker cache 形如:from ServiceWorker 是Web Worker的缓存设置,push cache 是HTTP2.0的新特性
Memory Cache 也就是内存中的缓存,主要包含的是当前中页面中已经抓取到的资源,读取内存中的数据肯定比磁盘快,内存缓存虽然读取高效,但生命周期有限,受浏览器的Tab页面所影响。
其中一块重要的缓存资源是preloader相关指令(例如)下载的资源。这是浏览器提供的预加载器实现的资源下载,可以一边进行渲染流水线的进行,一边通过网络请求获取资源。
通过rel=“preload”进行内容预加载 - HTML(超文本标记语言) | MDN
Disk Cache 也就是存储在硬盘中的缓存,读取速度慢点,但是什么都能存储到磁盘中,比之 Memory Cache 胜在容量和存储时效性上。
在所有浏览器缓存中,Disk Cache 覆盖面基本是最大的。它会根据 HTTP Herder 中的字段判断哪些资源需要缓存,哪些资源可以不请求直接使用,哪些资源已经过期需要重新请求。
HTTP缓存的资源,大部分会放入Disk Cache中进行缓存,但和memory cache 的边界除了size,我分不清。
缓存策略是基于HTTP协议进行的,是浏览器端和服务端的通用缓存策略。
其中的字段以及所代表的含义可以参照分级策略、缓存流程图 和 cache-control 流程图进行复习并讲解。
可以分为三层,根据命中顺序自底向上解释:
缓存机制分为强缓存和协商缓存。优先级较高的是强缓存,在命中强缓存失败的情况下,才会走协商缓存。
强缓存是利用 http 头中的 Expires 和 Cache-Control 两个字段来控制的。当请求再次发出时,浏览器会根据其中的 expires 和 cache-control 判断目标资源是否“命中”强缓存,若命中且有效,则直接从缓存中获取资源,不会再与服务端发生通信。
expires
expires 是一个时间戳,接下来如果我们试图再次向服务器请求资源,浏览器就会先对比本地时间和 expires 的时间戳,如果本地时间小于 expires 设定的过期时间,那么就直接去缓存中取这个资源。
如果服务端和客户端的时间设置不同(或者我直接手动去把客户端的时间改掉)那么 expires 将无法达到我们的预期判断能力
考虑到 expires 的局限性,HTTP1.1 新增了 Cache-Control 字段来完成 expires 的任务。
Cache-Control
在 Cache-Control 中,我们通过 max-age 来控制资源的有效期。max-age 不是一个时间戳,而是一个unix时间戳。
协商缓存依赖于服务端与浏览器之间的通信。
协商缓存机制下,浏览器需要向服务器去询问缓存的相关信息,进而判断是重新发起请求下载最新的资源还是从本地获取缓存的资源。 如果服务端提示缓存资源未改动(Not Modified),资源会被重定向到浏览器缓存,这种情况下网络请求对应的状态码是 304
Last-Modified
Last-Modified 是一个时间戳,如果我们启用了协商缓存,它会在首次请求时随着 Response Headers 返回.
随后我们每次请求时,会带上一个叫 If-Modified-Since 的时间戳字段,它的值正是上一次 response 返回给它的 last-modified 值.
存在的问题:
Etag
Etag 是由服务器为每个资源生成的唯一的hash值,这个hash是基于文件内容编码的,只要文件内容不同,它们对应的 Etag 就是不同的。
Etag 的生成过程需要服务器额外付出开销,会影响服务端的性能,这是它的弊端。
缓存判断整体流程如图所示,对应的分级策略和强制缓存、协商缓存以按照相应颜色进行标注。
推荐fireFox浏览器来感受资源缓存以及请求的过程,因为 他会有链接到MDN… 哈哈, 放一个截图。
该字段对于缓存是否生效有如下判断流程:
s-maxage 优先级高于 max-age,两者同时出现时,优先考虑 s-maxage。如果 s-maxage 未过期,则向代理服务器请求其缓存内容。注意:s-maxage仅在代理服务器中生效,客户端中我们只考虑max-age 详细的文章:浅谈 Web 缓存 | AlloyTeam
更正: 判断cache-control 中,第一个判断是 no-store
todo:更正图片、no-store 和 no-cache 本质区别在于什么?不都是发送网络请求吗?
done: no-store表示不允许缓存,通常用于某些变化非常频繁的数据,no-cache表示可以缓存,但是使用之前必须要去服务器验证是否过期,是否有最新的版本
浏览器和服务器的缓存策略
浏览器缓存机制有四个方面,获取资源时请求的优先级依次排列如下:
memory cache 和 Disk Cache
Memory Cache 也就是内存中的缓存,主要包含的是当前中页面中已经抓取到的资源,读取内存中的数据肯定比磁盘快,内存缓存虽然读取高效,但生命周期有限,受浏览器的Tab页面所影响。
其中一块重要的缓存资源是preloader相关指令(例如)下载的资源。这是浏览器提供的预加载器实现的资源下载,可以一边进行渲染流水线的进行,一边通过网络请求获取资源。
通过rel=“preload”进行内容预加载 - HTML(超文本标记语言) | MDN
Disk Cache 也就是存储在硬盘中的缓存,读取速度慢点,但是什么都能存储到磁盘中,比之 Memory Cache 胜在容量和存储时效性上。
在所有浏览器缓存中,Disk Cache 覆盖面基本是最大的。它会根据 HTTP Herder 中的字段判断哪些资源需要缓存,哪些资源可以不请求直接使用,哪些资源已经过期需要重新请求。
HTTP cache
缓存策略是基于HTTP协议进行的,是浏览器端和服务端的通用缓存策略。
其中的字段以及所代表的含义可以参照分级策略、缓存流程图 和 cache-control 流程图进行复习并讲解。
分级策略
可以分为三层,根据命中顺序自底向上解释:
强缓存
强缓存是利用 http 头中的 Expires 和 Cache-Control 两个字段来控制的。当请求再次发出时,浏览器会根据其中的 expires 和 cache-control 判断目标资源是否“命中”强缓存,若命中且有效,则直接从缓存中获取资源,不会再与服务端发生通信。
expires
expires 是一个时间戳,接下来如果我们试图再次向服务器请求资源,浏览器就会先对比本地时间和 expires 的时间戳,如果本地时间小于 expires 设定的过期时间,那么就直接去缓存中取这个资源。
考虑到 expires 的局限性,HTTP1.1 新增了 Cache-Control 字段来完成 expires 的任务。
Cache-Control
在 Cache-Control 中,我们通过 max-age 来控制资源的有效期。max-age 不是一个时间戳,而是一个unix时间戳。
协商缓存
协商缓存依赖于服务端与浏览器之间的通信。
协商缓存机制下,浏览器需要向服务器去询问缓存的相关信息,进而判断是重新发起请求下载最新的资源还是从本地获取缓存的资源。 如果服务端提示缓存资源未改动(Not Modified),资源会被重定向到浏览器缓存,这种情况下网络请求对应的状态码是 304
Last-Modified
Last-Modified 是一个时间戳,如果我们启用了协商缓存,它会在首次请求时随着 Response Headers 返回.
随后我们每次请求时,会带上一个叫 If-Modified-Since 的时间戳字段,它的值正是上一次 response 返回给它的 last-modified 值.
存在的问题:
Etag
Etag 是由服务器为每个资源生成的唯一的hash值,这个hash是基于文件内容编码的,只要文件内容不同,它们对应的 Etag 就是不同的。
Etag 的生成过程需要服务器额外付出开销,会影响服务端的性能,这是它的弊端。
缓存流程图
缓存判断整体流程如图所示,对应的分级策略和强制缓存、协商缓存以按照相应颜色进行标注。
cache-control 流程图
该字段对于缓存是否生效有如下判断流程: