前端工程师需要了解的缓存策略

82 阅读4分钟

浏览器的缓存主要有强制缓存协商缓存两种。

在需要请求资源时,会先向浏览器缓存查找结果,根据该结果的缓存规则来决定是否使用该缓存结果。

1 缓存策略

  • 存在该缓存结果和缓存标识,结果未失效,强制缓存生效,直接返回该缓存结果
  • 存在该缓存结果和缓存标识,但结果已失效,强制缓存失效,使用协商缓存,浏览器携带缓存标识向服务器发起请求,由服务器根据缓存标识来决定是否使用缓存:协商缓存失效,返回200和新的请求结果协商缓存生效,返回304,直接拿浏览器缓存内的缓存结果。
  • 不存在该缓存结果和缓存标识,则直接向服务器发起请求。

2 缓存控制字段

2.1 Expires

HTTP/1.0 控制网页缓存的字段,其值为服务器返回该请求结果缓存的到期时间,即再次发起该请求时,如果客户端的时间小于Expires的值时,直接使用缓存结果。

示例:Fri, 29 Oct 2021 07:05:15 GMT

现在浏览器的默认使用的是HTTP/1.1,到了HTTP/1.1,Expires已经被 Cache-Control 替代,原因在于Expires控制缓存的原理是使用客户端的时间与服务端返回的时间做对比,如果客户端与服务端的时间由于某些原因(时区不同;客户端和服务端有一方的时间不准确)发生误差,那么强制缓存直接失效,那么强制缓存存在的意义就毫无意义。

2.2 Cache-Control

Cache-Control 主要用于控制网页缓存,主要取值为:

  • public:所有内容都将被缓存(客户端和代理服务器都可缓存)
  • private:所有内容只有客户端可以缓存,Cache-Control的默认取值
  • no-cache:客户端缓存内容,但是是否使用缓存则需要经过协商缓存来验证决定
  • no-store:所有内容都不会被缓存,即不使用强制缓存,也不使用协商缓存
  • max-age=xxx (xxx is numeric):缓存内容将在xxx秒后失效

Cache-Control 的优先级高于 Expires

2.3 Pragma

HTTP/1.0 中的与 Cache-Control 的 no-cache 相同,但一般用来兼容 HTTP/1.0

2.4 Last-Modified / If-Modified-Since

  • Last-Modified 是服务器响应请求时,通过该字段携带资源在服务器最后的修改时间。
  • If-Modified-Since 是浏览器下次请求时,将上次返回的 Last-Modified 字段值携带

服务器接收请求时,将接收到的 If-Modified-Since 字段值内容与该资源最后修改时间相比,资源更新则返回200和新的请求结果,资源未更新则返回304且使用缓存的结果。

2.5 Etag / If-None-Match —— 优先级更高

  • Etag 是服务器响应请求时,返回的该资源文件的唯一标识
  • If-None-Match 是浏览器下次请求时,将上次返回的 Etag 字段值携带

服务器接收请求时,将接收到的 If-None-Match 字段值与存在服务器的该资源的 Etag 值进行对比,不同则返回 200 和最新结果,相同则返回304且使用缓存的结果。

2.6 Vary

一般用来区分移动端还是桌面端,以防止返回错误文件。

小结

    1. 强制缓存优先于协商缓存,强制缓存生效(Cache-Control / Expires)则直接使用强制缓存,强制缓存失效才判断是否使用协商缓存。
    1. 协商缓存(Etag / If-None-Match —— 优先级更高, Last-Modified / If-Modified-Since )由服务器决定是否使用缓存,若缓存生效则返回304且使用缓存结果,若缓存失效则返回200且返回新的结果。

3 缓存存储

3.1 内存缓存 —— memory cache

  • 快速读取: 内存缓存会将编译解析后的文件直接存入该进程的内存中,占据该进程一定的内存资源,以便于下次使用时快速读取。
  • 时效性: 一但该进程关闭,则该进程的内存会清空。
  • js 和 图片 文件一般会在解析后放入内存缓存中,刷新页面直接从内存缓存中读取。

3.2 硬盘缓存 —— disk cache

  • 缓存直接写入硬盘中,读取时需要对文件进行 I/O 操作,重新解析内容,读取相对内存缓存更复杂,速度相对更慢。
  • css 文件 一般会存在硬盘缓存中,每次重新渲染页面都需要重新从硬盘缓存中读取。