Skip to content

【综合】浏览器缓存—强制缓存和协商缓存(对比缓存) #29

@Dliling

Description

@Dliling

浏览器缓存
又称HTTP缓存,即协议层的缓存。。百科解释为:是为了节约网络的资源加速浏览,浏览器在用户磁盘上对最近请求过的文档进行存储,当访问者再次请求这个页面时,浏览器就可以从本地磁盘显示文档,这样就可以加速页面的阅览。简而言之就是,浏览器对用户最近访问的文档进行存储,当用户再次访问这个页面时,浏览器就可以直接从存储中加载文档。
优点:
(1)减少等待时间和网络流量,从而减少资源显示所需时间
(2)不必每次都从服务器获取数据,减少服务器压力,提升网站加载速度

缓存过程

infoflow 2020-06-29 16-15-50

由上图可以看出:
(1)浏览器每次请求,都先在浏览器缓存中查找该请求对应的结果以及缓存标识
(2)浏览器每次拿到请求结果都会将该结果和缓存标识存入浏览器缓存中

我们根据是否需要向服务器重新发起请求将缓存过程分为两个部分,分别是强制缓存和协商缓存

强制缓存

先来看下强制缓存时的工作模式:

infoflow 2020-06-28 21-08-35

从上图可以看出,只有缓存失效了,才会去服务器获取最新资源的方式就是强制缓存。可以造成强制缓存的两个字段是响应头(Response Headers)中的Expires和Cache-Control。

HTTP/1.0——Expires
表示缓存到期时间,即有效时间+当时服务器时间,然后将这个时间设置在header中返回给服务器。这个时间是一个绝对时间。如:
Expires: Mon, 29 Jun 2020 07:16:03 GMT
响应头中设置这个字段后,告诉浏览器在未过期之前不用再次请求。
但是这个字段有缺点,由于是绝对时间,当浏览器和服务器时间不一致时,会导致缓存失效。

HTTP/1.1——Cache-Control
已知Expires的缺点后,在HTTP/1.1中,新增Cache-Control,表示缓存资源的最大有效时间,在这段时间内,客户端不再向服务器发送请求。这个时间是一个相对时间,即使客户端时间发生改变,相对时间也不会发生改变,这样可以保证服务器和客户端时间的一致性。下面列举一些Cache-Control的取值:
(1)no-cache:在发布缓存副本之前,强制要求缓存把请求提交给原始服务器进行验证
(2)no-store:所有内容都不缓存
(3)max-age=xxx:缓存内容在xxx秒后失效。即在xxx秒内再次请求时,直接使用缓存结果,强制缓存生效。

从HTTP/1.1开始,Expires逐步被Cache-Control取代,当两者同时存在时,只有Cache-Control生效。

协商缓存(对比缓存)
协商缓存就是强制缓存失效后,浏览器携带缓存标识向服务器发起请求,由服务器根据缓存标识决定是否使用缓存的过程,主要有以下两种情况:
(1)协商缓存生效,返回304,如下
infoflow 2020-06-30 16-56-05

(2)协商缓存失效,返回200和请求结果,如下
infoflow 2020-06-30 16-56-21

协商缓存的标识是放在响应头中和请求结果一起返回的。控制协商缓存的字段分别有:Last-Modified / If-Modified-Since 和Etag / If-None-Match,Etag / If-None-Match优先级比较高。

Last-Modified:服务器响应请求之后,返回该资源在服务器最后被修改的时间。
If-Modified-Since:客户端再次发起请求时,携带上次请求返回的Last-Modified,服务器收到请求后,发现请求头中有If-Modified-Since字段,会将If-Modified-Since的值与该资源在服务器最后被修改的时间比较,若Last-Modified大于If-Modified-Since,则返回200和最新资源,否则返回304,代表资源无更新,可以继续使用缓存。
缺点:
(1)时间单位只能到秒级,频繁更新时缓存是不可用的
(2)若资源是服务器动态生成的,它的最后更新时间永远是生成时间,尽管文件可能没有变化,所以缓存不可用。

Etag:服务器响应请求时,返回当前资源文件的一个唯一标识。Etag: W/"<etag_value>"Etag: "<etag_value>"
If-None-Match:客户端再次发起请求时,携带上次请求返回的Etag值,服务器收到请求后,发现请求头中有If-None-Match,会根据If-None-Match的字段值与Etag值做比较,一致则返回304,继续使用缓存,不一致返回200和新资源文件。

用户行为对浏览器缓存的控制
(1)地址栏访问,链接跳转是正常行为,将会触发浏览器缓存机制
(2)F5刷新,浏览器会设置max-age=0,跳过强制缓存判断,进行协商缓存判断
(3)ctrl+F5刷新,跳过强制缓存和协商缓存,直接从服务器拉取资源

移动端缓存处理
移动端需要考虑网络问题。强制缓存没有问题,只要缓存不过期就不会发送请求。但是在协商缓存的情况下,304问题会造成很多无用请求。每次在使用缓存前,都要发送请求向服务器确认,导致网络延时。

一次完美的缓存必须保证两点:
(1)数据缓存之后,尽量减少服务器端请求
(2)如果资源更新,必须使得客户端的资源一起更新

所以,我们一般在资源文件后面加上标识,如config.v1.js之类的,然后给资源设置较长的缓存时间,如一年
Cache-Control: max-age=31536000
这样,就不会造成304的回包现象。然而资源一旦更新,可以改变资源后面的标识符,实现静态资源非覆盖式更新。

总结
强制缓存优先于协商缓存。若强制缓存(Expires和Cache-Control)生效则使用强制缓存,不生效使用协商缓存(Last-Modified / If-Modified-Since 和Etag / If-None-Match)。协商缓存由服务器决定是否使用缓存,若协商缓存生效,则返回304,继续使用缓存资源,若不生效返回200和请求结果,再存入浏览器缓存。

infoflow 2020-06-30 17-33-42

参考:
浏览器缓存篇
彻底理解浏览器的缓存机制

为你推荐:
【第903期】浏览器缓存机制剖析
【第887期】浏览器的缓存机制小结
【第613期】浏览器缓存,想说爱你不容易
HTTP缓存
强制缓存和协商缓存的区别

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions