游览器缓存--强缓存与协商缓存

119 阅读7分钟

强缓存:直接使用缓存中的数据

(http1.0)Expires

(http1.1)Cache-Control/Max-Age

cache-control优先级高于expires,cache-control有很多指令:

cache-control:

- max-age: 强缓存的时间
- s-maxage:代理服务器的资源过期时间,且仅当设置了public属性值时才有效

- no-cache:允许缓存,但每次都要协商
- no-store:禁止缓存和协商

- public:允许代理服务器缓存资源
- private:不允许代理服务器缓存资源,只有浏览器可以缓存

- immutable:就算过期了也不用协商,资源就是不变的
- max-stale:过期了一段时间的话,资源也能用
- stale-while-revalidate:在验证(协商)期间,返回过期的资源
- stale-if-error:验证(协商)出错的话,返回过期的资源
- must-revalidate:不允许过期了还用过期资源,必须等协商结束

协商缓存:强缓存失效后,和服务器协商,是否可以使用缓存中的数据

(http1.0)If-Modified-Since/Last-Modified

(http1.1)If-None-Match/E-tag

image.png

image.png

http1.0中的缓存控制:

  1. 强缓存

    • Pragma:严格来说,它不属于专门的缓存控制头部,但是它设置no-cache时可以让本地强缓存失效(属于编译控制,来实现特定的指令,主要是因为兼容http1.0,所以以前又被大量应用)
    • Expires:服务端配置的,属于强缓存,用来控制在规定的时间之前,浏览器不会发出请求,而是直接使用本地缓存,注意,Expires一般对应服务器端时间,如Expires:Fri, 30 Oct 1998 14:19:41
  2. 协商缓存

    • If-Modified-Since/Last-Modified:这两个是成对出现的,属于协商缓存的内容,其中浏览器的头部是If-Modified-Since,而服务端的是Last-Modified,它的作用是,在发起请求时,如果If-Modified-SinceLast-Modified匹配,那么代表服务器资源并未改变,因此服务端不会返回资源实体,而是只返回头部,通知浏览器可以使用本地缓存。Last-Modified,顾名思义,指的是文件最后的修改时间,而且只能精确到1s以内

http1.1中的缓存控制:

  1. 强缓存

    • Cache-Control:缓存控制头部,有no-cache、max-age等多种取值
    • Max-Age:服务端配置的,用来控制强缓存,在规定的时间之内,浏览器无需发出请求,直接使用本地缓存,注意,Max-Age是Cache-Control头部的值,不是独立的头部,譬如Cache-Control: max-age=3600,而且它值得是绝对时间,由浏览器自己计算
  2. 协商缓存

    • If-None-Match/E-tag:这两个是成对出现的,属于协商缓存的内容,其中浏览器的头部是If-None-Match,而服务端的是E-tag,同样,发出请求后,如果If-None-MatchE-tag匹配,则代表内容未变,通知浏览器使用本地缓存,和Last-Modified不同,E-tag更精确,它是类似于指纹一样的东西,基于FileEtag INode Mtime Size生成,也就是说,只要文件变,指纹就会变,而且没有1s精确度的限制。

http2中的缓存机制

HTTP/2.0引入了一些新的缓存机制,以提高性能和效率。下面是HTTP/2.0中的一些缓存机制:

  1. Server Push:HTTP/2.0允许服务器在响应中主动推送资源给客户端,而无需客户端明确请求。这样可以减少客户端发起的请求次数,加快页面加载速度。
  2. 多路复用:HTTP/2.0使用二进制分帧技术,允许多个请求和响应同时在一个TCP连接上进行传输。这样可以避免了HTTP/1.x中的队头阻塞问题,提高了并发性能。对于缓存来说,多路复用意味着多个资源可以同时从服务器传输到客户端,加快了页面加载速度。
  3. Header 压缩:HTTP/2.0使用了HPACK算法对请求和响应的Header进行压缩。这减少了Header的大小,减少了网络传输的数据量,提高了性能。对于缓存来说,压缩的Header减少了缓存的存储空间和传输成本。
  4. Stream Prioritization:HTTP/2.0引入了流的优先级概念,可以对请求和响应进行优先级排序。这样可以确保重要资源的优先传输,提高用户体验。对于缓存来说,优先级可以帮助确定哪些资源应该被缓存,以及缓存资源的有效期。
  5. Server Push Cache:HTTP/2.0中的Server Push允许服务器主动推送资源给客户端,但客户端可以选择拒绝接收。客户端可以使用Cache Digests机制来告知服务器哪些资源已经被缓存,从而避免不必要的推送。这样可以减少不必要的网络传输和资源浪费。

这些缓存机制的引入使得HTTP/2.0在性能和效率方面有了显著的改进,提供了更好的用户体验和更高的网络效率。

Max-Age相比Expires?

  • Expires使用的是服务器端的时间

    • 但是有时候会有这样一种情况-客户端时间和服务端不同步
    • 那这样,可能就会出问题了,造成了浏览器本地的缓存无用或者一直无法过期
    • 所以一般http1.1后不推荐使用Expires
  • Max-Age使用的是客户端本地时间的计算,因此不会有这个问题

  • 因此推荐使用Max-Age

  • 注意,如果同时启用了Cache-ControlExpiresCache-Control优先级高。

E-tag相比Last-Modified?

Last-Modified

  • 表明服务端的文件最后何时改变的
  • 它有一个缺陷就是只能精确到1s,如果文件修改速度非常快,在1s内完成修改,协商缓存的有效性判断也会不准确,无法请求到最新的资源。
  • 然后还有一个问题就是有的服务端的文件会周期性的改变,导致缓存失效
  • 如果对文件进行编辑,但是内容没有发生任何变化,文件最新修改时间也会更新,从而导致协商缓存有效性的判断不准确,会重新请求新的资源。

E-tag

  • 是一种指纹机制,代表文件相关指纹
  • 只有文件变才会变,也只要文件变就会变,
  • 也没有精确时间的限制,只要文件一遍,立马E-tag就不一样了
  • 服务器生成文件资源的ETag需要额外的计算开销,若资源存在尺寸大、数据多、修改频繁等问题,则会影响服务器性能。
  • ETag在服务器集群场景下,准确率不高。

如果同时带有E-tagLast-Modified,服务端会优先检查E-tag

为什么要使用游览器缓存?

网页中的代码和资源都是从服务器下载的,如果服务器和用户的浏览器离得比较远,那下载过程会比较耗时,网页打开也就比较慢。下次再访问这个网页的时候,又要重新再下载一次,如果资源没有啥变动的话,那这样的重新下载就很没必要。所以,HTTP 设计了缓存的功能,可以把下载的资源保存起来,再打开网页的时候直接读缓存,速度自然会快很多。

而且,每个请求都要服务端做相应的处理,比如解析 url,读取文件,返回响应等,而服务器能同时处理的请求是有上限的,也就是负载是有上限的,所以如果能通过缓存减少没必要的资源的请求,就能解放服务器,让它去处理一些更有意义的请求。

综上,为了提高网页打开速度降低服务器的负担,HTTP 设计了缓存的功能。

网站的缓存设置

入口html文件设置 no-cache ,其他资源设置 max-age

这样入口文件会缓存但是每次都协商,保证能及时更新,而其他资源不发请求,减轻服务端压力

如果缓存没过期但是资源更新了怎么办:html 文件协商后发现有更新会下载新 html,这时候关联了其他 hash 的文件,浏览器会下载新的,不会走到之前文件的缓存。

强制刷新的实现原理就是设置了 Cache-Control 为 no-cache,这个行为被 Chrome DevTools 隐藏了,用 Charles 抓包就能看到。

清空缓存并强制刷新的功能,那个是清掉本地的缓存再去协商,能保证一定是拿到最新的资源。