前言
web缓存是前端性能优化、网页打开速度中非常重要的一个环节. 好的缓存策略可以缩短网页请求资源的距离,减少延迟,并且由于缓存文件可以重复利用,还可以减少带宽,降低网络负荷、降低服务器负载, 网上有很多讲缓存的 但是很多都讲的不是很清楚 所以基于自己的理解 希望可以讲的清楚一些
缓存分类
缓存的种类有很多,其大致可归为两类:私有缓存与共享缓存。共享缓存存储的响应能够被多个用户使用。私有缓存只能用于单独用户。本文将主要介绍浏览器缓存,除此之外还有网关缓存、CDN、反向代理缓存和负载均衡器等部署在服务器上的缓存方式,为站点和 web 应用提供更好的稳定性、性能和扩展性。
浏览器缓存
浏览器缓存也就是http缓存 常见的 HTTP 缓存只能存储 GET 响应 缓存状态是由 http请求的header中参数决定的 , http缓存分为两种
- 强制缓存
- 协商缓存
强制缓存
强制缓存在http中有两个参数可以控制Expires
和Cache-Control: max-age=<seconds>
Expires
: 是http/1.0定义的 ,是服务器 响应消息头字段,用来指定资源到期的时间,是服务器端的具体的时间点, 在响应 http 请求时告诉浏览器在过期时间前浏览器可以直接从浏览器缓存取数据,而无需再次请求。 (如果在Cache-Control响应头设置了 "max-age" 或者 "s-max-age" 指令,那么 Expires 头会被忽略。)
示例
Expires: Wed, 21 Oct 2020 07:28:00 GMT
Cache-Control
: 是在http/1.1定义 , 请求头和响应头都支持这个属性。通过它提供的不同的值来定义缓存策略, 在响应消息头字段中Cache-Control
值为max-age=<seconds>
的时候表明此资源使用强制缓存,max-age是距离请求发起的时间的秒数,标识此资源不过期的最大时间。针对应用中那些不会改变的文件,通常可以手动设置一定的时长以保证缓存有效,例如图片、css、js等静态资源。
示例
cache-control: max-age=31536000
强制缓存如果命中, 浏览器会直接拦截此次请求, 并直接返回200状态码,使用本地缓存的资源副本
协商缓存
协商缓存在http中有也有两个参数可以控制Pragma: no-cache
和Cache-Control: no-cache
Pragma 是HTTP/1.0标准中定义的一个header属性,请求中包含Pragma的效果跟在头信息中定义Cache-Control: no-cache相同,但是HTTP的响应头没有明确定义这个属性,所以它不能拿来完全替代HTTP/1.1中定义的Cache-control头。通常定义Pragma以向后兼容基于HTTP/1.0的客户端。
Cache-Control: no-cache
如果强制缓存未命中或者缓存已过期的情况下,浏览器会尝试使用协商缓存
请求时 请求头会携带 Cache-Control: no-cache
和 Pragma: no-cache
服务器会优先读取Cache-Control: no-cache
协商缓存有两种校验器
- 强校验器 (
ETag / If-none-match
)
ETag
是作为缓存的一种强校验器,ETag 响应头是一个对用户代理(User Agent, 我们理解为浏览器就行)不透明的值。对于像浏览器这样的HTTP UA,不知道ETag代表什么,不能预测它的值是多少。如果资源请求的响应头里含有ETag, 客户端可以在后续的请求的头中带上 If-None-Match 头来验证缓存 值为上次返回的ETag值, 服务器端对 ETag 属性之间的比较采用的是弱比较算法,即两个文件除了每个比特都相同外,内容一致也可以认为是相同的。例如,如果两个页面仅仅在页脚的生成时间有所不同,就可以认为二者是相同的。 - 弱校验器 (
last-modified / If-Modified-Since
)Last-Modified
响应头可以作为一种弱校验器。说它弱是因为它只能精确到一秒。如果在这一秒内文件有改动的话, 浏览器无法获取到最新的资源 , 如果响应头里含Last-Modified
,客户端可以在后续的请求中带上 If-Modified-Since 来验证缓存
ps : 当与 If-Modified-Since 一同使用的时候,If-None-Match 优先级更高(假如服务器支持的话)。 当文件未改变的时候 ,服务器端必须返回响应码 304 , 服务器端在生成状态码为 304 的响应的时候,必须同时生成以下会存在于对应的 200 响应中的首部:Cache-Control
、Content-Location
、Date
、ETag
、Expires
和 Vary
。
总结
上图
当然实际浏览器与服务器的校验更加复杂 参数也更多