发表于: 2019-12-07 23:52:39

1 1075


今日完成的事

       调试公告接口

明日计划的事

      继续调试接口

收获

      继续写下前端缓存,

昨天写到请求网路,今天继续写下去


按失效策略分类

memory cache 是浏览器为了加快读取缓存速度而进行的自身的优化行为,不受开发者控制,也不受 HTTP 协议头的约束,算是一个黑盒。Service Worker 是由开发者编写的额外的脚本,且缓存位置独立,出现也较晚,使用还不算太广泛。所以我们平时最为熟悉的其实是 disk cache,也叫 HTTP cache (因为不像 memory cache,它遵守 HTTP 协议头中的字段)。平时所说的强制缓存,对比缓存,以及 Cache-Control 等,也都归于此类。

强制缓存 (也叫强缓存)

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

强制缓存直接减少请求数,是提升最大的缓存策略。 它的优化覆盖了文章开头提到过的请求数据的全部三个步骤。如果考虑使用缓存来优化网页性能的话,强制缓存应该是首先被考虑的。

可以造成强制缓存的字段是 Cache-control 和 Expires。


Expires

这是 HTTP 1.0 的字段,表示缓存到期时间,是一个绝对的时间 (当前时间+缓存时间),如

Expires: Thu, 10 Nov 2017 08:45:11 GMT

在响应消息头中,设置这个字段之后,就可以告诉浏览器,在未过期之前不需要再次请求。

但是,这个字段设置时有两个缺点:

由于是绝对时间,用户可能会将客户端本地的时间进行修改,而导致浏览器判断缓存失效,重新请求该资源。此外,即使不考虑自信修改,时差或者误差等因素也可能造成客户端与服务端的时间不一致,致使缓存失效。

写法太复杂了。表示时间的字符串多个空格,少个字母,都会导致非法属性从而设置失效。


Cache-control

已知Expires的缺点之后,在HTTP/1.1中,增加了一个字段Cache-control,该字段表示资源缓存的最大有效时间,在该时间内,客户端不需要向服务器发送请求

这两者的区别就是前者是绝对时间,而后者是相对时间。如下:

Cache-control: max-age=2592000

下面列举一些 Cache-control 字段常用的值:(完整的列表可以查看 MDN)

max-age:即最大有效时间,在上面的例子中我们可以看到

must-revalidate:如果超过了 max-age 的时间,浏览器必须向服务器发送请求,验证资源是否还有效。

no-cache:虽然字面意思是“不要缓存”,但实际上还是要求客户端缓存内容的,只是是否使用这个内容由后续的对比来决定。

no-store: 真正意义上的“不要缓存”。所有内容都不走缓存,包括强制和对比。

public:所有的内容都可以被缓存 (包括客户端和代理服务器, 如 CDN)

private:所有的内容只有客户端才可以缓存,代理服务器不能缓存。默认值。

这些值可以混合使用,例如 Cache-control:public, max-age=2592000。在混合使用时,它们的优先级如下图:

这里有一个疑问:max-age=0 和 no-cache 等价吗?从规范的字面意思来说,max-age 到期是 应该(SHOULD) 重新验证,而 no-cache 是 必须(MUST) 重新验证。但实际情况以浏览器实现为准,大部分情况他们俩的行为还是一致的。(如果是 max-age=0, must-revalidate 就和 no-cache 等价了)

顺带一提,在 HTTP/1.1 之前,如果想使用 no-cache,通常是使用 Pragma 字段,如 Pragma: no-cache(这也是 Pragma 字段唯一的取值)。但是这个字段只是浏览器约定俗成的实现,并没有确切规范,因此缺乏可靠性。它应该只作为一个兼容字段出现,在当前的网络环境下其实用处已经很小。

总结一下,自从 HTTP/1.1 开始,Expires 逐渐被 Cache-control 取代。Cache-control 是一个相对时间,即使客户端时间发生改变,相对时间也不会随之改变,这样可以保持服务器和客户端的时间一致性。而且 Cache-control 的可配置性比较强大。

Cache-control 的优先级高于 Expires,为了兼容 HTTP/1.0 和 HTTP/1.1,实际项目中两个字段我们都会设置。



返回列表 返回列表
评论

    分享到