探究缓存机制

深入强缓存,协商缓存,了解DNS缓存和CDN缓存

Posted by AzirKxs on 2022-10-25
Estimated Reading Time 9 Minutes
Words 2.6k In Total
Viewed Times

HTTP中的强缓存与协商缓存 - 掘金 (juejin.cn)

缓存:浏览器缓存、DNS缓存和CDN缓存_Qssn丶的博客-CSDN博客_浏览器缓存和dns缓存

从输入URL开始建立前端知识体系 - 掘金 (juejin.cn)

HTTP 缓存技术 - 协商缓存_51CTO博客_协商缓存

我们都知道当我们在浏览器中打开一个页面时,浏览器会根据你输入的URL到对应的服务器上请求你想要的数据资源。但这个过程中可能页面可能需要等待一段时间(白屏时间)才能渲染到你的页面中。

当你想要提高用户体验时,那就不得不提各种缓存技术了,例如:DNS缓存、CDN缓存。浏览器缓存、页面本地缓存等等,有一个良好的缓存策略可以减低重复资源的请求,降低服务器的开销,提高用户页面的加载速度。

介绍各种各样的缓存策略,因为都是规范相关的内容,于是就看了多篇文章各取优点进行一个整理(缝合一下,再夹带一点私活)

浏览器缓存

浏览器缓存分为强缓存和协商缓存,当我们输入URL时,浏览器首先会解析出协议、主机、端口、路径等信息,并构造一个 HTTP 请求,在发送http请求之前会先判断一下是否有缓存。浏览器缓存是建立在重复请求的前提下的,简单概述一下浏览器缓存的流程

浏览器再次发送请求时:

  • 首先判断强缓存,强缓存生效直接使用强缓存(200 from memory、from disk 先从内存,再从硬盘),如果强缓存不生效就换采用协商缓存策略
  • 没有设置协商缓存就直接重新请求(200)
  • 设置了协商缓存则由服务器判断缓存是否失效,没有失效就继续使用缓存(304,同强缓存的获取方式),失效则返回新的文件(200)

另一种说法:

  • 浏览器发送请求前,根据请求头的expirescache-control判断是否命中(包括是否过期)强缓存策略,如果命中,直接从缓存获取资源,并不会发送请求。如果没有命中,则进入下一步。

  • 没有命中强缓存规则,浏览器会发送请求,根据请求头的If-Modified-SinceIf-None-Match判断是否命中协商缓存,如果命中,直接从缓存获取资源。如果没有命中,则进入下一步。

  • 如果前两步都没有命中,则直接从服务端获取资源。

强缓存

强制缓存就是向浏览器缓存查找该请求结果,并根据该结果的缓存规则来决定是否使用该缓存结果的过程。强缓存又分为两种ExpiresCache-Control

img

expires

  • 版本:HTTP/1.0
  • 来源:存在于服务端返回的响应头中
  • 语法:Expires: Wed, 22 Nov 2019 08:41:00 GMT
  • 缺点:服务器的时间和浏览器的时间可能并不一致导致失效

Expireshttp1.0的规范,用于表示资源的过期时间的请求头字段,值是一个绝对时间,是由服务器端返回的。

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

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

Cache-Control

  • 版本:HTTP/1.1
  • 来源:响应头和请求头
  • 语法:Cache-Control:max-age=3600
  • 缺点:时间最终还是会失效

expires在客户端本地时间和服务器时间不一致时会产生误差,因此在http1.1中提出了Cache-Control,它设置了一个字段max-age是从当前时间开始计时,在该时间内不与服务器重新请求新的数据,是优于expires的,因此在同时启用的时候它的优先级高于expires

协商缓存

协商缓存就是强制缓存失效后,浏览器携带缓存标识向服务器发起请求,由服务器根据缓存标识决定是否使用缓存的过程

HTTP 缓存技术 - 协商缓存_服务器_02

1.当浏览器发起一个资源请求时,浏览器会先判断本地是否有缓存记录,如果没有会向浏览器请求新的资源。

2.如果有缓存记录,先判断强缓存是否存在(cache-control优先于expires,后面会说),如果强缓存的时间没有过期则返回本地缓存资源(状态码为200)

3.如果强缓存失效了,客户端会发起请求进行协商缓存策略,首先服务器判断Etag标识符,如果客户端传来标识符和当前服务器上的标识符是一致的,则返回状态码 304 not modified(不会返回资源内容)

判断过程如下:

  • 浏览器请求资源,服务器返回报文中加入Etag值,资源更新则Etag值也会更新。
  • 浏览器再次请求资源,此时请求报文会加入If-None-Match,值为上一次响应报文的Etag值。
  • 服务器比对报文的If-None-Match和当前的Etag是否一致,不一致则更新Etag并且返回,下一次浏览器请求Etag将传输新的值。如果一致表示资源没有更新,状态码返回304,浏览器从本地缓存获取,此时响应头会同时返回Etag值。(虽然没有变化)

4.如果没有Etag字段,则比对Last-Modified。

  • 浏览器第一次向服务端请求之后,服务端响应中加入Last-Modified 字段,表示资源最后一次修改时间。
  • 浏览器再次请求,在请求报文中会加入If-Modified-Since 字段,字段值等于上一次浏览器返回的Last-Modified (最后一次修改时间)。
  • 服务器比对Last-Modified 和If-Modified-Since 字段,如果不一致则接受资源并且返回更新之后的资源,如果一致表示资源没有更新,返回304状态码,此时浏览器会从本地缓存获取资源文件。值得注意的是,本地请求如果是304,此时响应头中不会再添加Last-Modified字段。

5.如果Etag和服务器端上的不一致,重新获取新的资源,并进行协商缓存返回数据。

状态码区别

  • 200 请求成功,服务器返回全新的数据
  • 200 from memory cache / from disk cache 本地强缓存还在有效期,直接使用本地缓存
  • 304 请求成功,走了协商缓存,服务器判定(EtagLast-modified)没有过期,告知浏览器使用缓存

用户行为对缓存的影响

  1. 当ctrl+f5强制刷新网页时,直接从服务器加载,跳过强缓存和协商缓存。
  2. 当f5刷新网页时,跳过强缓存,但是会检查协商缓存。
  3. 浏览器地址栏中写入URL,回车 浏览器发现缓存中有这个文件了,不用继续请求了,直接去缓存拿。

缓存的位置

service worker

Service Worker 是运行在浏览器背后的独立线程,一般可以用来实现缓存功能,使用 Service Worker的话,传输协议必须为 HTTPS。因为 Service Worker 中涉及到请求拦截,所以必须使用 HTTPS 协议来保障安全。Service Worker 的缓存与浏览器其他内建的缓存机制不同,它可以让我们自由控制缓存哪些文件、如何匹配缓存、如何读取缓存,并且缓存是持续性的。

Memory Cache

Memory Cache 也就是内存中的缓存,主要包含的是当前中页面中已经抓取到的资源,例如页面上已经下载的样式、脚本、图片等。读取内存中的数据肯定比磁盘快,内存缓存虽然读取高效,可是缓存持续性很短,会随着进程的释放而释放。 一旦我们关闭Tab页面,内存中的缓存也就被释放了

Disk Cache

Disk Cache 也就是存储在硬盘中的缓存,读取速度慢点,但是什么都能存储到磁盘中,比之 Memory Cache 胜在容量和存储时效性上。

Push Cache

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

DNS缓存

有DNS的地方,就有缓存。浏览器、操作系统、Local DNS、根域名服务器,它们都会对DNS结果做一定程度的缓存:

  • 首先查找浏览器自身的缓存
  • 然后是本机hosts,如果还是没有,则查找本地DNS服务器
  • 本地DNS服务器一般是动态分配的或者我们自己指定的地址(当然这里还有个路由器的缓存)
  • 再查找不到,则向根服务器发送递归查找,边缘DNS > 顶级DNS > 二级DNS > 三级DNS(也就是网站注册的)

CDN缓存

在浏览器本地缓存失效后,浏览器会向CDN边缘节点发起请求。类似浏览器缓存,CDN边缘节点也存在着一套缓存机制。CDN边缘节点缓存策略因服务商不同而不同,但一般都会遵循http标准协议,通过http响应头中的Cache-control判断资源是否过期
其优势是:

1.CDN节点解决了跨运营商和跨地域访问的问题,访问延时大大降低。
2.大部分请求在CDN边缘节点完成,CDN起到了分流作用,减轻了源服务器的负载。


如果这篇文章对你有帮助,可以bilibili关注一波 ~ !此外,如果你觉得本人的文章侵犯了你的著作权,请联系我删除~谢谢!