前言
缓存就是首次请求之后保存一份请求资源的响应副本,当用户再次发送请求的时候,如果能命中就拦截请求,将之前存储的响应副本返回给用户,这样就避免了重新向服务器请求资源。
这篇文章主要是介绍浏览器缓存的三个方面:
- HTTP缓存
- Service Worker缓存
- Push缓存
HTTP缓存
HTTP缓存分为强缓存和协商缓存。
强缓存
概念:浏览器判断所请求的目标资源命中之后,可以直接从强缓存中返回响应,不需要经过服务器。
响应头的一些信息
与强缓存相关的响应头有:expires和cache-control。
expires:是HTTP1.0协议中声明用来控制缓存失效日期的时间戳,是由服务器端指定后通过响应头告知浏览器的,浏览器接受该字段响应体后进行缓存。之后如果再次发送相同的请求,如果expires和本地的时间戳对比,本地的时间戳小于expires那么就没有失效,可以从缓存中直接获取返回的内容。
但expires有着局限性。
expires对时间戳有着很强的依赖,客户端的本地时间戳与服务端的时间戳不同步,或者对客户端的本地时间进行修改的话,那么这个缓存失效的时间可能会与预期的不符。所以出现了cache-control
cache-control:设置max-age,这个是以秒作为单位的。例如:max-age=3153600,请求资源后的3153600秒内有效,解决了服务器端和客户端本地时间戳不同步的问题。
cache-control还有其他属性
no-cache和no-store
no-cache:开启协商缓存
no-store:不开启缓存
private和public
明确响应资源是否可被代理服务器进行缓存。
private:不能被代理服务器缓存
public:能被代理服务器缓存
max-age
告诉客户端响应资源的过期时长。
memory cache 与 disk cache 的区别?
都是强缓存,memory cache的缓存来自内存,disk cache缓存来自硬盘上。
- memory cache:当前tab页关闭后,数据将不存在(资源被释放掉了),再次打开相同的页面时,原来的 memory cache 会变成 disk cache
- disk cache:关闭tab页甚至关闭浏览器后,数据依然存在,下次打开仍然会是 from disk cache
其中一些体积不大的js文件,css样式表会放在memory cache,体积较大的放在disk cache。
协商缓存
概念:在使用本地缓存之前,需要向服务端发一次GET请求,与之协商当前浏览器所保存到本地缓存是否过期了。
协商缓存的标识
last-modified
文件最近一次修改的时间戳。
例如:客户端需要向服务器请求一个abc.js文件,使用的是协商缓存,那么首次返回该资源的响应头就包含 last-modified
字段,该字段属性值为JavaScript文件最近一次修改的时间戳,此时请求该文件的时候会包含一个if-modified-since
字段,这个值为last-modified
,接着服务器会将两者进行对比,如果相同的话就可以走缓存,不相同服务器端还需要重新请求全新的文件资源。
last-modified的不足.
- 当文件资源发生了改变,但是文件内容没有发生改变,时间戳还会进行修改,服务端就会重新请求全新资源,会造成网络带宽资源的浪费
- 该时间戳单位为秒,当文件修改速度很快,无法识别该文件资源的更新
所以引出了ETag。
ETag
服务器端根据不同的资源生成的一个字符串,类似文件指纹,只要文件内容发生了改变,ETag标签就会不同。
ETag的优先级比last-modified高。
首次请求的响应头
less
Content-Type:image/jpeg
ETag:"c39046a19cd8354384c2de0c32ce7ca5"
Last-Modified:Fri,12 Jul 2019 06:45:17 GMT
Content-Length:9887
再次发起请求,会将之前响应头中ETag的字段值作为此次请求头中If-None-Match
字段,提供给服务器进行缓存有效性检验。
less
If-None-Match:"c39046a19cd8354384c2de0c32ce7ca5"
If-Modified:Fri,12 Jul 2019 06:45:17 GMT
//再次响应
Content-Type:image/jpeg
ETag:"c39046a19cd8354384c2de0c32ce7ca5"
Last-Modified:Fri,12 Jul 2019 06:45:17 GMT
Content-Length:0
如果验证缓存有效的话就返回304重定向到本地缓存。
缺点
- 服务器对生成文件资源的ETag需要付出额外的计算开销,如果资源过大的话,会影响服务器性能
缓存决策
缓存方案
- HTML使用协商缓存
- JS,图片,css使用强缓存
这样就可以解决在客户端可以实时地获取最新的内容,固定的资源会在客户端进行尽可能久的保存。
Service Worker
Service Worker
是运行在浏览器背后的独立线程,一般可以用来实现缓存功能。
- 必须是
HTTPS
。因为它涉及请求拦截,所以必须使用HTTPS
协议来保障安全。 Service Worker
缓存不同于其他机制,它可以让我们自由控制缓存哪些文件、如何匹配缓存、如何读取缓存,并且缓存是持续性的。
Push缓存
Push Cache
(推送缓存) 是 HTTP/2
中的内容,是基于HTTP2
的连接的,当连接断开的时候,就会丢失资源,所以它适合资源推送到页面间隔较短的使用场景。
缓存优先级:当以上 3 种缓存都没有命中的时候,它才会被使用。
应用场景
- 有效利用服务器的空闲时间进行资源推送
- 推送HTML中的内联资源,例如js脚本,小图标,样式表
总结
- 缓存优先级