通过复用以前获取的资源,可以显著提高网站和应用程序的性能。Web 缓存减少了等待时间和网络流量,因此减少了显示资源表示形式所需的时间。通过使用 HTTP缓存,变得更加响应性。

通过下图来分析强缓存和协商缓存:

专业术语

  • 缓存命中率:从缓存中得到数据的请求与所有请求数的比例,理想状态越高越好
  • 过期内容:超出设置的有效时间,被标记为“陈旧”内容,通常过期内容不能用于回复客户端请求,必须重新请求源服务器内容或者验证缓存内容是否仍然存在
  • 验证:验证缓存中的过期内容是否有效,如果有效重新更改过期时间
  • 失效:将失效的内容资源从缓存中移除

浏览器缓存主要是http缓存机制

<meta http-equiv=”pragma” content=”no-store” />

让浏览器不缓存当前页面,但是代理服务器不解析HTML内容,一般广泛用于http信息控制

浏览器加载流程

  1. 浏览器根据资源请求头信息判断是否命中强缓存,如果命中则直接加载缓存资源,并不会发送请求到服务器
  2. 如果未命中强缓存,则浏览器会将资源请求发送到服务器,服务器来检查浏览器本地缓存是否失效,若可以使用则不会返回新资源,浏览器继续使用本地缓存
  3. 如果未命中协商缓存,则服务器会将完整的资源返回给浏览器,浏览器加载并更新新资源

缓存类型

  1. 强缓存

强缓存主要是根据http返回头内的expires与cache-control两个字段控制的,用来显示资源的过期时间

浏览器根据第一次请求的请求头部信息,判断是否需要将该资源缓存至本地,强缓存主要是根据http返回头内的expires与cache-control两个字段控制的,用来显示资源的过期时间,当下次访问该资源的时候浏览器会根据头部信息检查是否命中强缓存,若命中则直接返回请求状态码200,项目继续使用本地缓存资源。

expires解释

缓存期间,用来制定资源到期时间,是服务端的具体时间点,也就是说,Expires=max-age + 请求时间,需要和last-modified结合使用

但是cache-control的优先级更高,Expires是web服务器响应消息头字段,在响应http请求时告诉浏览器,在资源过期前可以直接在浏览器缓存中取资源,不需要请求

Expires是资源过期的绝对时间即命中缓存,由于失效时间是一个相对本地时间的,本地客户端时间修改之后会导致缓存混乱,于是才有cache-control

Cache-control

cache-control是相对服务器的时间,例如:cache-control: 3600,代表资源有效时间是3600秒。由于是跟服务端时间对比,所以一般不会出现时间偏差

cache-contorl与expires可以再服务端同时开启或者任意一个,但是cache-control的优先级较高

cache-control可以有多个字段组合而成,主要是参数如下:

  • max-age:指定一个时间长度,在这个时间长度内缓存是有效的单位是s,第一次返回资源的时候,expires也会返回 * 在缓存期间其没有禁用缓存,再次访问则会直接命中,不会请求浏览器。
    过期机制中,最重要的指令是 “max-age=<seconds>“,表示资源能够被缓存(保持新鲜)的最大时间。相对Expires而言,max-age是距离请求发起的时间的秒数。针对应用中那些不会改变的文件,通常可以手动设置一定的时长以保证缓存有效,例如图片、css、js等静态资源。
  • s-maxage:同max-age,覆盖max-age,expires,但仅限于共享缓存,在私有缓存中会被忽略
  • no-store: 不设置缓存,缓存中不得存储任何关于客户端请求和服务端响应的内容。每次由客户端发起的请求都会下载完整的响应内容。
  • no-cache:缓存但必须重新验证,如下头部定义,此方式下,每次有请求发出时,缓存会将此请求发到服务器(译者注:该请求应该会带有与本地缓存相关的验证字段),服务器端会验证请求中所描述的缓存是否过期,若未过期(注:实际就是返回304),则缓存才使用本地缓存副本。
  • public:共有缓存,”public” 指令表示该响应可以被任何中间人(译者注:比如中间代理、CDN等)缓存。若指定了”public”,则一些通常不被中间人缓存的页面(译者注:因为默认是private)(比如 带有HTTP验证信息(帐号密码)的页面 或 某些特定状态码的页面),将会被其缓存。
  • private:而 “private” 则表示该响应是专用于某单个用户的,中间人不能缓存此响应,该响应只能应用于浏览器私有缓存中。
  • must-revalidate: 缓存在考虑使用一个陈旧的资源时,必须先验证它的状态,已过期的缓存将不被使用。

2.协商缓存

协商缓存主要是在未命中强缓存,则会将请求发送至服务器,服务器根据http信息头的last-modify/if-modify-since 或者etag/if-none-match来判断是否命中,如果命中则http状态码为304,浏览器从缓存中加载资源

last-modify/if-modify-since

  1. 浏览器第一次请求资源的时候,服务器的返回header会加上last-modify,last-modify是资源的最后修改时间
  2. 当浏览器再次请求该资源的时候,发送的请求头中会包含,if-modify-since,该值为资源返回之前的last-modify,服务器收到if-modify-since,根据最后修改时间判断是否命中
  3. 如果命中缓存,http状态码为304不会返回资源,且不会返回last-modify,由于是对比的服务器时间,所以客户端与服务端的时间差不会导致问题
  4. 但是有时候通过最后修改时间也不一定准确,因为文件修改了但是内容可以一致,于是出现了etag/if-none-match

etag/if-none-match

与last-modify/if-modify-since不同的是,etag/if-none-match返回的是一个校验码,etag可以保证资源唯一,资源变化会导致etag变化,资源变化之后etag变化,服务器根据请求头内的if-none-match来命中资源

etag扩展说明,etag会对每一个url生成一个唯一值,当资源变化时etag也会发生改变,

etag的生成规则为:
1.文件i-node编号,是Linux、Unix文件识别的编号,=
2.文件最后修改时间 
3.文件大小

生成etag可以使用其中一种或者几种因素,使用碰撞散列函数来生成,理论上也会有重复,但是概率很小

有了last-modified为什么还要etag?

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

  1. Last-Modified标注的最后修改只能精确到秒级,如果某些文件在1秒钟以内,被修改多次的话,它将不能准确标注文件的修改时间
  2. 如果某些文件会被定期生成,当有时内容并没有任何变化,但Last-Modified却改变了,导致文件没法使用缓存
  3. 有可能存在服务器没有准确获取文件修改时间,或者与代理服务器时间不一致等情形
  4. Etag是服务器自动生成或者由开发者生成的对应资源在服务器端的唯一标识符,能够更加准确的控制缓存。
  5. Last-Modified与ETag是可以一起使用的,服务器会优先验证ETag,一致的情况下,才会继续比对Last-Modified,最后才决定是否返回304。

Pragma头

Pragma是HTTP/1.0标准中定义的一个header属性,请求中包含Pragma的效果跟在头信息中定义Cache-Control: no-cache相同,但是HTTP的响应头没有明确定义这个属性,所以它不能拿来完全替代HTTP/1.1中定义的Cache-control头。通常定义Pragma以向后兼容基于HTTP/1.0的客户端。

Vary

Vary: User-Agent

哪种情况下使用 Vary: 对于User-Agent 头部信息,例如你提供给移动端的内容是不同的,可用防止你客户端误使用了用于桌面端的缓存。  

用户行为

用户操作Expires/cache-controlLast-modified/Etag
地址栏回车有效有效
页面链接跳转有效有效
新开窗口有效有效
前进、后退有效有效
F5刷新无效有效
Ctrl + F5刷新(强制刷新)无效无效

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注