一、说明

内容来自《前端工程化体系设计与实践》

浏览器缓存静态资源实际上是通过 HTTP 协议缓存策略,有两种策略分别是强制缓存协商缓存

强制缓存会根据过期时间判断是使用本地缓存还是请求新的资源。

协商缓存每次都会发出请求,经过服务器对比之后决定采用本地缓存还是新的资源。

使用哪种缓存策略是通过 HTTP 协议的 header 信息决定。

二、强制缓存:Expires 和 Cache-control

Expires 和 max-age 是强制缓存的关键的信息,都会在 http 响应的 header 信息。

1、Expires

Expires 是通过指定一耳光明确的时间点作为缓存资源的过期时间,在这个时间之前,客户端都是使用本地缓存的文件来响应 HTTP 请求,不会向服务器发出实体请求不过调试的时候能够发现这个请求,并且这个请求是 200

Expires 的优点:

  • 在缓存过期时间内减少客户端的 HTTP 请求,不仅节省客户端处理时间和提高 Web 应用执行速度,也减少了服务器负载以及客户端网络资源的损耗

Expires 的 header 信息示例:

Expires:Wed, 23 Aug 2019 14:00:00 GMT

上面的意思是缓存过期时间是 2019年8月23日 14:00:00

Expires 的 缺点:

  • 指定的时间是以服务端为准但是客户端进行过期判断时是将本地的时间和这个时间进行对比
  • 如果客户端端时间和服务端时间存在差异,则会存在问题

2、Cache-control

为了解决 Expires 的缺点,HTTP 1.1 增加了新的 header 字段 Cache-control 来更精准的控制缓存常用的 Cache-control 信息有下面几个:

  • no-cache 和 no-store
  • public 和 private
  • max-age

1)no-cache 和 no-store

no-cache 不是禁止缓存的意思,需要先和服务器确认返回的响应时否发生了变化,如果资源没变化,使用缓存的副本

no-store 是禁止缓存,每次资源请求都会向服务器发送新的请求

2)public 和 private

public 表示可以被浏览器和中间CDN缓存(一般不用,都是使用 max-age),而 private 表示可以被浏览器缓存但是不能被 CDN 缓存

3)max-age

这个是最重要的 Cache-control 信息,一般都会通过 max-age 控制缓存的有效时长。

从请求的时刻开始计算,能够控制最长保留多久,单位是 s

比如 max-age=3600 表示浏览器在1小时内使用缓存,不会发送实体请求到服务器。

22403-m1ijpw6jcd.png

相比于 Expires ,max-age 通过控制时间长度而不需要与服务端时间戳进行计算,控制的更加精准,没有时间误差。

3、没有指定 no-cache 的缓存判断流程图

35766-d6hjfawd0ic.png

三、协商缓存

1、Etag

Etag 是服务器给资源分配的字符串形式唯一性标识,作为响应的 header 信息返回给浏览器,浏览器在 Cache-control指定 no-cache 或者是 max-age 和 expires 都过期的情况下,将 Etag 值通过 If-none-match 作为请求首部信息发送给服务器,服务器接收到请求之后,对比锁清秋资源的 Etag 值是否改变:

  • 如果没改变,会返回 304 Not Modified ,并且根据之前的缓存策略分配新的 Cache-control 信息
  • 如果发生了改变,会返回新的资源并且分配新的 Etag

01681-jb0z844w4vm.png

如果要强制使用协商缓存,则需要将 Cache-control 设置为 no-cache,这样不回去判断 max-age 和 Expires ,每次都会经过服务器的 Etag 对比。

05869-tfbr4gckzn.png

协商缓存并非比强制缓存低级,而是要看使用场景,在 HTML 文件场景下,如果一个 URL www.example.com/index.html 其中 index.html 是不能强制缓存的,因为要保证内容的实时更新,因此必须使用协商缓存