详解浏览器的缓存机制
“缓存一直是前端优化的主战场,利用好缓存就成功了一半。本篇从HTTP请求和响应的头域入手,让你对浏览器缓存有个整体的概念。最终你会发现强缓存,协商缓存 和 启发式缓存是如此的简单。”
导读
浏览器对于请求资源,拥有一系列成熟的缓存策略。按照发生的时间顺序分别为存储策略、过期策略、协商策略,其中存储策略在收到响应后应用,过期策略、协商策略在发送请求前应用。流程图如下所示:
废话不多说,我们先来看两张表格。
1. HTTP Header中与缓存有关的Key:
key描述存储策略过期策略协商策略
Cache-Control指定缓存机制,覆盖其它设置✔️✔️
Pragmahttp1.0字段,指定缓存机制✔️
Expireshttp1.0字段,指定缓存的过期时间✔️
Last-Modified资源最后一次的修改时间✔️
ETag唯一标识请求资源的字符串✔️
2. 缓存协商策略用于重新验证缓存资源是否有效,有关的Key如下:
key描述
If-Modified-Since缓存校验字段,值为资源最后一次的修改时间,即上次收到的Last-Modified值
If-Unmodified-Since同上,处理方式与之相反
If-Match缓存校验字段,值为唯一标识请求资源的字符串,即上次收到的ETag值
If-None-Match同上,处理方式与之相反
各个头域(key)的作用
Cache-Control
浏览器缓存里,Cache-Control是金字塔顶尖的规则,它藐视一切其他设置,只要其他设置与其抵触,一律覆盖之。
不仅如此,它还是一个复合规则,包含多种值,横跨存储策略、过期策略两种,同时在请求头和响应头都可设置。
语法为:“Cache-Control : cache-directive”。
Cache-directive共有如下12种(其中请求中指令7种,响应中指令9种):
Cache-directive描述存储策略过期策略请求字段响应字段
public资源将被客户端和代理服务器缓存✔️✔️
private资源仅被客户端缓存,代理服务器不缓存✔️✔️
no-store请求和响应都不缓存✔️✔️✔️
no-cache相当于max-age:0,must-revalidate即资源被缓存,但是缓存立刻过期,同时下次访问时强制验证资源有效性✔️✔️✔️✔️
max-age缓存资源,但是在指定时间(单位为秒)后缓存过期✔️✔️✔️✔️
s-maxage同上,依赖public设置,覆盖max-age,且只在代理服务器上有效。✔️✔️✔️
max-stale指定时间内,即使缓存过时,资源依然有效✔️✔️
min-fresh缓存的资源至少要保持指定时间的新鲜期✔️✔️
must-revalidation / proxy-revalidation如果缓存失效,强制重新向服务器(或代理)发起验证(因为max-stale等字段可能改变缓存的失效时间)✔️✔️
only-if-cached仅仅返回已经缓存的资源,不访问网络,若无缓存则返回504✔️
no-transform强制要求代理服务器不要对资源进行转换,禁止代理服务器对 Content-Encoding,Content-Range,Content-Type字段的修改(因此代理的gzip压缩将不被允许)✔️✔️
假设所请求资源于4月5日缓存,且在4月12日过期。
当max-age 与 max-stale 和 min-fresh 同时使用时,它们的设置相互之间独立生效,最为保守的缓存策略总是有效。这意味着,如果max-age=10 days,max-stale=2 days,min-fresh=3 days,那么:
根据max-age的设置,覆盖原缓存周期, 缓存资源将在4月15日失效(5+10=15);
根据max-stale的设置,缓存过期后两天依然有效,此时响应将返回110(Response is stale)状态码,缓存资源将在4月14日失效(12+2=14);
根据min-fresh的设置,至少要留有3天的新鲜期,缓存资源将在4月9日失效(12-3=9);
由于客户端总是采用最保守的缓存策略,因此,4月9日后,对于该资源的请求将重新向服务器发起验证。
非常好我支持^.^
(0) 0%
不好我反对
(0) 0%