浏览器缓存

# 浏览器缓存

# 按失效策略分类:强制缓存/强缓存

含义:当客户端请求后,会先访问缓存数据库看缓存是否存在。如果存在则直接返回;不存在则请求真的服务器,响应后再写入缓存数据库。

强制缓存直接减少请求数,是提升最大的缓存策略。 造成强缓存的字段是 Cache-control 和 Expires

  • Expires 这个字段表示缓存的时间,是一个绝对的时间(当前时间+缓存时间),如:

    expires: Mon, 01 Mar 2021 10:25:05 GMT
    
    1

    在响应头中设置该字段,意思即为告诉浏览器,在未过期之前不需要在修改。 缺点:

    1. 是绝对时间,用户可以修改本地客户端时间,导致浏览器判断缓存失效,重新请求资源。时差或误差等因素也可能造成客户端与服务端的时间不一致,致使缓存失效。
    2. 写法复杂, 表示时间的字符串多个空格,少个字母,非法属性都会导致设置失效。
  • Cache-control 该字段表示资源缓存的最大有效时间(相对时间),在该时间内,客户端不需要向服务器发送请求。如:

    Cache-control: max-age=2592000
    
    1

    常用的值:

    1. max-ages:即最大的有效时间,
    2. must-revalidate:如果超过了 max-age 的时间,浏览器必须向服务器发送请求,验证资源是否有效
    3. no-cache:字面意思是“不要缓存”,但实际上还是要求客户端缓存内容的,只是是否使用这个内容由后续的对比来决定
    4. no-store:真正意义上的“不要缓存”,所有内容都不走缓存,包括强制和对比
    5. public: 所有的内容都可以被缓存(包括客户端和代理服务器,如 CDN)
    6. private:所有的内容只有客户端才可以缓存,代理服务器不能缓存。默认值

    这些值可以混合使用,混合使用时注意优先级: no-store —— no-cache —— public/private —— max-age 注意:

    1. max-age=0, must-revalidate 和 no-cache 等价
    2. Cache-control 的优先级比 Expires 高

# 协商缓存/对比缓存

当强制缓存失效时,就需要使用对比缓存,由服务器决定缓存内容是否失效。 浏览器先请求缓存数据库,返回一个缓存标识,之后浏览器拿这个标识和服务器通讯。如果缓存没有失效,则返回 HTTP 状态码表示继续使用,于是客户端继续使用缓存;如果失效,则返回新的数据和缓存规则,浏览器响应数据后,再把规则写入到缓存数据库。

协商缓存和没有缓存在请求数上是一致的(请求 —— 处理 - 响应),HTTP 返回 304 是优化的响应,通过减少响应体体积,来缩短网络传输时间。有以下两组字段

  • Last-Modified & If-Modified-Since 通过该字段告知客户端,资源最后一次被修改的时间。如:

    Last-Modified: Mon, 10 Nov 2018 09:10:11 GMT
    
    1

    浏览器将这个值和内容一起记录在缓存数据库中;下次请求资源时,浏览器从自己的缓存中找出“不确定是否过期的”缓存,在请求头中将上次的 Last-Modified 的值写入到请求头的 If-Modified-Since 字段;服务器会把If-Modified-SinceLast-Modified的值进行对比,如果一样,则表明未修改,响应 304,反之,表示修改了,响应 200 状态码,并返回数据。 缺点:

    1. 如果资源更新的速度是秒以下单位,该缓存不能使用,因为它的单位时间最低是秒
    2. 如果文件是服务器是动态生成的,该方法的最后修改时间永远是生成的时间,尽管文件可能没有变化,所以起不到缓存的作用。
  • Etag & If-None-Match Etag 存储的是文件的特殊标识,服务器存储这文件的 Etag 字段; 下次请求资源时,浏览器在请求头中将 Etag 的值写入到请求头中的 If-None-Match; 服务器会比较 Etag 与 If-None-Match 的值,如果一样返回 304, 如果不一样返回 200 和新资源。

    Etag 的优先级高于 Last-Modified

# 浏览器请求资源过程

  1. 调用 Service Worker 的 fetch 事件响应

  2. 查看 memory cache

  3. 查看 disk cache,细分: (1)如果有强缓存且未失效,则使用强制缓存,不请求服务器,状态码全是 200 (2) 如果强制缓存失效,使用协商缓存,比较后确定返回 304 还是 200

  4. 发送网络请求,等待网络响应

  5. 把响应内容存入 disk cache(如果 HTTP 头信息配置可以存的话)

  6. 把响应内容的引用存入 memory cache(无视 HTTP 头信息的配置)

  7. 把响应内容存入 Service Worker 的 Cache Storage(如果 Service Worker 的脚本调用了 cache.put())

上次更新: 3/22/2021, 3:12:39 PM