浏览器缓存(Service Worker、Memory Cache、disk Cache、强缓存、协商缓存、Ctr F5、Disable Cache、强缓存假象)详解

目录

浏览器缓存

缓存种类

Service Worker

Memory Cache

preloader

disk cache

添加缓存位置流程 

强制缓存 (强缓存)

Expires

Cache-control 

协商缓存(对比缓存)

Etag作用

Pragma

协商缓存使用注意

缓存标志优先级

请求流程

浏览器操作对缓存的影响

Ctr F5(硬性重新加载、强制刷新)

Disable cache

Ctr Shift Delete

强缓存假象

缓存案例


浏览器缓存

浏览器在本地磁盘对用户最近请求过的文档(文件)进行存储(缓存),以便在下一次访问时重复使用,即当访问者再次访问同一页面时,浏览器就可以直接从本地磁盘加载文档,从而节省带宽、提升访问速度、降低服务器压力。

缓存种类

浏览器缓存按位置分类有3种,它们的优先级是:(由上到下寻找,找到即返回;找不到则继续)

  1. Service Worker
  2. Memory Cache
  3. Disk Cache
  4. 网络请求

我们可以在 Chrome 的开发者工具中F12,Network -> Size 一列看到一个请求最终的处理方式:如果是大小 (多少 K, 多少 M 等) 就表示是网络请求,否则会列出 from memory cache, from disk cache from ServiceWorker
浏览器缓存(Service Worker、Memory Cache、disk Cache、强缓存、协商缓存、Ctr F5、Disable Cache、强缓存假象)详解_第1张图片

按缓存方式分类有2种

1.强制缓存(强缓存)

2.协商缓存 (对比缓存)

Service Worker

一种在浏览器后台运行的JavaScript脚本,它可以拦截和处理网页发出的网络请求,以及管理缓存和离线数据。Service Worker可以让网页在离线状态下仍能正常访问,并且可以提高网页的性能和响应速度。它由开发者编写的额外的脚本控制,且缓存位置独立。

可以在 F12 中的Application下看到浏览器缓存(Service Worker、Memory Cache、disk Cache、强缓存、协商缓存、Ctr F5、Disable Cache、强缓存假象)详解_第2张图片

Service Worker可以实现以下功能:

  • 离线缓存:Service Worker可以缓存网页资源,使得用户在离线状态下仍能访问已经缓存的资源。
  •  推送通知:Service Worker可以接收来自服务器的推送通知,并在用户离线时显示通知。
  • 资源拦截:Service Worker可以拦截网页发出的网络请求,并根据需要返回缓存中的资源或者从服务器请求最新的资源。
  • 跨域通信:Service Worker可以和其他域名的网页进行通信,从而实现一些跨域的功能。

如果 Service Worker 没能命中缓存,一般情况会使用 fetch() 方法继续获取资源。这时浏览器就去 memory cache 或者 disk cache 进行下一次找缓存的工作了。经过 Service Worker 的 fetch() 方法获取的资源,即便它并没有命中 Service Worker 缓存,甚至实际走了网络请求,也会标注为 from ServiceWorker
注意:为了保证安全性,Service Worker只能在HTTPS协议下使用。

Memory Cache

内存中的缓存(与之相对 disk cache 就是硬盘上的缓存)。不受开发者控制,也不受 HTTP 协议头的约束,是一个黑盒。

几乎所有的网络请求资源都会被浏览器自动加入到 memory cache 中。但是也正因为数量很大但是浏览器占用的内存不能无限扩大这样两个因素,memory cache 只能是“短期存储”。通常浏览器窗口中的一个页签TAB 关闭后该次浏览的 memory cache 便失效 (为了给其他 TAB 腾出位置)。而如果极端情况下 (例如一个页面的缓存就占用了超级多的内存),那可能在 TAB 没关闭之前,排在前面的缓存就已经失效了

注意:在从 memory cache 获取缓存内容时,浏览器会忽视例如 max-age=0, no-cache 等头部配置。例如页面上存在几个相同 src 的图片,即便它们可能被设置为不缓存,但依然会从 memory cache 中读取。这是因为 memory cache 只是短期使用,大部分情况生命周期只有一次浏览而已。而 max-age=0 在语义上普遍被解读为“不要在下次浏览时使用”,所以和 memory cache 并不冲突。

如果想让一个资源进入缓存,就连短期也不行,就使用 no-store。存在这个头部配置的话,即便是 memory cache 也不会存储,自然也不会从中读取了。

preloader

一种浏览器技术,用于在网页加载过程中预先加载一些资源(如图片、CSS文件、JavaScript文件等),以便在用户访问网页时可以更快地呈现页面内容。Preloader通常使用JavaScript代码来实现,它可以在网页加载时异步加载资源,而不会阻塞页面的渲染(一边解析执行 js/css,一边去请求下一个(或下一批)资源)。

被 preloader 请求够来的资源就会被放入 memory cache 中,供之后的解析执行操作使用。

Web Performance Calendar » Who’s Afraid of the Big Bad Preloader?

disk cache

disk cache 也叫 HTTP cache(它遵守 HTTP 协议头中的字段,平常说的强制缓存,对比缓存,以及 Cache-Control 等),是存储在硬盘上的缓存,因此它是持久存储的,是实际存在于文件系统中的。而且它允许相同的资源在跨会话,甚至跨站点的情况下使用,例如两个站点都使用了同一张图片。

disk cache 会严格根据 HTTP 头信息中的各类字段来判定哪些资源可以缓存,哪些资源不可以缓存;哪些资源是仍然可用的,哪些资源是过时需要重新请求的。当命中缓存之后,浏览器会从硬盘中读取资源,虽然比起从内存中读取慢了一些,但比起网络请求还是快了不少的。绝大部分的缓存都来自 disk cache。

disk cache同样也会面临空间不足的时候,当 disk cache 空间不足时,会根据 LRU

(Least Recently Used,最近最少使用)算法淘汰掉最近最少使用的缓存数据,腾出空间存储新的缓存数据。LRU 算法的基本思想是,当缓存空间满时,将最近最少使用的缓存数据淘汰掉,腾出空间存储新的缓存数据。具体实现方式是,每次访问缓存数据时,都将该数据移动到链表头部,这样链表尾部的数据就是最近最少使用的数据,可以直接淘汰掉。

添加缓存位置流程 

  1. 根据 Service Worker 中的 handler 决定是否存入 Cache Storage (额外的缓存位置)。
  2. 根据 HTTP 头部的相关字段(Cache-control, Pragma 等)决定是否存入 disk cache
  3. memory cache 保存一份资源 的引用,以备下次使用。
     

强制缓存 (强缓存)

当客户端请求后,会先访问缓存数据库看缓存是否存在。如果存在则直接返回;不存在则请求真的服务器,响应后再写入缓存数据库。强制缓存直接减少请求数,是提升最大的缓存策略。 

可以造成强制缓存的字段是 Cache-control Expires

Expires

Expires 字段是http1.0时的规范,用于表示资源过期时间的请求头字段,它的值为一个绝对时间的GMT格式的时间字符串,是由服务器端返回的。比如

Expires:Mon,18 Oct 2066 23:59:59 GMT

在响应消息头中,设置这个字段之后代表这个资源在此时间之前命中缓存。

在浏览器第一次请求资源时,服务器端的响应头会附上Expires这个响应字段,当浏览器在下一次请求这个资源时会根据上次的Expires字段是否使用缓存资源(当请求时间小于服务端返回的到期时间,直接使用缓存数据)

注意:expires是根据本地时间来判断的,假设客户端和服务器时间不同,会导致缓存命中误差

Cache-control 

为解决expires根据本地时间判断导致缓存命中误差,在http1.1规范中,提出了cache-control字段,且同时使用时优先级高于Expires

下面是几个常用的属性设置:

  • max-age:即最大有效时间,为相对时间,例如Cache-Control:max-age=3600,代表着资源的有效期是3600秒,即客户端过了3600秒缓存过期。
  • s-maxage:和max-age一样,但这个是设定代理服务器的缓存时间
  • must-revalidate:如果超过了 max-age 的时间,浏览器必须向服务器发送请求,验证资源是否还有效。
  • no-cache:不使用本地缓存。需要使用缓存协商,先与服务器确认返回的响应是否被更改,如果之前的响应中存在ETag,那么请求的时候会与服务端验证,如果资源未被更改,则可以避免重新下载。
  • no-store::直接禁止浏览器缓存数据,每次用户请求该资源,都会向服务器发送一个请求,每次都会下载完整的资源。
  • public:所有的内容都可以被缓存 (包括客户端和代理服务器, 如 CDN)
  • private:只能被终端用户的浏览器缓存,不允许CDN等中继缓存服务器对其缓存。

完整的属性查看:Cache-Control - HTTP | MDN

协商缓存(对比缓存)

协商缓存是由服务器来确定缓存资源是否可用。

客户端与服务器端要通过某种标识来进行通信,从而让服务器判断请求资源是否可以缓存访问,这主要涉及到下面两组header字段,这两组搭档都是成对出现的,

即浏览器第一次发出请求的响应头带上Last-Modified或者Etag字段(若响应头没有Last-Modified或者Etag字段,则请求头也不会有对应的字段)

浏览器缓存(Service Worker、Memory Cache、disk Cache、强缓存、协商缓存、Ctr F5、Disable Cache、强缓存假象)详解_第3张图片

则后续请求则会带上对应的请求字段If-Modified-Since或者If-None-Match

浏览器缓存(Service Worker、Memory Cache、disk Cache、强缓存、协商缓存、Ctr F5、Disable Cache、强缓存假象)详解_第4张图片

  • Last-modified:本地文件最后修改时间,由服务器返回
  • if-modified-since:浏览器在请求数据时返回的,值是上次浏览器返回的Last-modified
  • ETag:一个文件的唯一标识符,当资源发生变化时这个ETag就会发生变化。弥补了上面last-modified可能出现文件内容没有变化但是last-modified发生了变化出现重新向服务器请求资源情况。这个值也是又服务器返回的
  • if-none-match:是浏览器请求数据时带上的字段,值是上次服务器返回的ETag
     

当请求头中的 If-Modified-Since、If-None-Match和服务器返回的Last-Modified、Etag分别对应相等时,表示资源没有改变,直接从缓存中取

Etag作用

HTTP1.1中Etag的出现主要是为了解决几个Last-Modified比较难以解决的问题:

1. 一些文件会周期性的更改,但是他的内容并不改变(仅仅改变的修改时间),这个时候我们并不希望客户端认为这个文件被修改了,而重新GET。

2. 某些文件修改非常频繁,比如在秒以下的时间内进行修改,(比方说1s内修改了N次),If-Modified-Since能检查到的粒度是s级的,这种修改无法判断(或者说UNIX记录MTIME只能精确到秒)。使用 Etag 就能够保证这种需求下客户端在 1 秒内能刷新多次。

3. 某些服务器不能精确的得到(获取)文件的最后修改时间。

Last-Modified与ETag是可以一起使用的,服务器会优先验证ETag,一致的情况下,才会继续比对Last-Modified,最后才决定是否返回304。

Pragma

Pragma 是一个在 HTTP/1.0 中规定的通用首部,这个首部的效果依赖于不同的实现,所以在“请求 - 响应”链中可能会有不同的效果。它用来向后兼容只支持 HTTP/1.0 协议的缓存服务器,那时候 HTTP/1.1 协议中的 Cache-Control 还没有出来。

备注: 由于 Pragma 在 HTTP 响应中的行为没有确切规范,所以不能可靠替代 HTTP/1.1 中通用首部 Cache-Control,尽管在请求中,假如 Cache-Control 不存在的话,它的行为与 Cache-Control: no-cache 一致。建议只在需要兼容 HTTP/1.0 客户端的场合下应用 Pragma 首部。

协商缓存使用注意

1. 分布式系统里last-modified需要保持一致,以免负载到不同的机器导致比对失败,从而返回新资源。

2. 分布式系统尽量关闭掉Etag,因为每一台服务器生成的Etag是不同的

缓存标志优先级

paragma -> Cache-control -> expires -> Etag -> last-modified 

请求流程

浏览器缓存(Service Worker、Memory Cache、disk Cache、强缓存、协商缓存、Ctr F5、Disable Cache、强缓存假象)详解_第5张图片

浏览器操作对缓存的影响

3种控制不走缓存的方法。

Ctr F5(硬性重新加载、强制刷新

去除浏览器在请求头加上的If-Modified-Since或If-None-Match字段,并加上Pragma: no-cache和Cache-Control: no-cache字段。

Pragma: no-cache和Cache-Control: no-cache表示不走强制缓存,由于去掉了协商缓存的字段,导致也无法走协商缓存。

浏览器缓存(Service Worker、Memory Cache、disk Cache、强缓存、协商缓存、Ctr F5、Disable Cache、强缓存假象)详解_第6张图片

注意:ctrl+f5只不过能够管控

你可能感兴趣的:(计算机网络知识,#,浏览器存储,强缓存假象,浏览器缓存机制详解,强缓存和协商缓存,缓存流程,缓存标志优先级,请求流程,浏览器不走缓存的方法详解)