HTTP缓存的存在是由于web前端的性能瓶颈大部分的缘由在于HTTP传输的时间耗费过长。若是可以减小这种HTTP请求的时间,对网页的性能来讲是很是大的提高,对于用户的体验也能获得极大的改善。html
HTTP缓存可分为强缓存(Cache-Control和Expires)以及协商缓存(Etag和Last-Modified)。前端
强缓存和协商缓存的区别在于:若是命中强缓存,会直接从缓存中读取资源,不向服务器请求。协商缓存则会向服务器请求确认资源是否过时。这也是缓存验证的顺序,先使用强缓存,后使用协商缓存。web
下面则简单介绍一下这两种缓存类型的标识浏览器
Cache-Control设置有效期max-age的值是时间的相对值。缓存
下面则简单介绍Cache-Control经常使用的使用值:性能优化
value | description |
---|---|
public | 代表响应能够被任何对象(包括:发送请求的客户端,代理服务器,等等)缓存。 |
private | 代表响应只能被单个用户缓存,不能做为共享缓存(即代理服务器不能缓存它),能够缓存响应内容。 |
no-cache | 在发布缓存副本以前,强制高速缓存将请求提交给原始服务器进行验证。 |
no-store | 缓存不该存储有关客户端请求或服务器响应的任何内容。 |
max-age=<seconds> | 设置缓存存储的最大周期,超过这个时间缓存被认为过时(单位秒)。与Expires相反,时间是相对于请求的时间。 |
must-revalidate | 缓存必须在使用以前验证旧资源的状态,而且不可以使用过时资源。 |
proxy-revalidate | 与must-revalidate做用相同,但它仅适用于共享缓存(例如代理),并被私有缓存忽略。 |
若想了解更详细的说明,可参考此连接:developer.mozilla.org/zh-CN/docs/…bash
Expires 响应头包含日期/时间, 即在此时候以后,响应过时。服务器
Expires设置的值是一个绝对值。前端性能
Expires: Wed, 21 Oct 2015 07:28:00 GMT
复制代码
Etag HTTP响应头是资源的特定版本的标识符。这可让缓存更高效,并节省带宽,由于若是内容没有改变,Web服务器不须要发送完整的响应。而若是内容发生了变化,使用ETag有助于防止资源的同时更新相互覆盖(“空中碰撞”)。性能
Etag的值是根据资源文件内容生成的一个hash值。
Etag: 33a64df551425fcc55e4d42a148795d9f25f89d4
复制代码
Last-Modified包含源头服务器认定的资源作出修改的日期及时间。 它一般被用做一个验证器来判断接收到的或者存储的资源是否彼此一致。因为精确度比 ETag 要低,因此这是一个备用机制。
Last-Modified的值是一个时间的绝对值。
Last-Modified: Wed, 21 Oct 2015 07:28:00 GMT
复制代码
304
状态码告诉客户端可读取缓存;若资源已修改则返回 200
状态码从新获取资源;图示:
如下的HTTP缓存验证说明是基于假设请求存在4个缓存头标记;
max-age
或s-max-age
,若是已设置则忽略Expires而且验证是否过时,不然验证Expires是否过时;其实按照MDN文档的说明,Last-Modified也是能够计算出一个缓存时间;下面是MDN文档的说明:
对于含有特定头信息的请求,会去计算缓存寿命。好比Cache-control: max-age=N的头,相应的缓存的寿命就是N。一般状况下,对于不含这个属性的请求则会去查看是否包含Expires属性,经过比较Expires的值和头里面Date属性的值来判断是否缓存还有效。若是max-age和expires属性都没有,找找头里的Last-Modified信息。若是有,缓存的寿命就等于头里面Date的值减去Last-Modified的值除以10(注:根据rfc2626其实也就是乘以10%)。
缓存时间计算公式:
expirationTime = responseTime + freshnessLifetime - currentAge
200 (from cache memory || from disk memory)
,若是缓存过时,则使用协商缓存; 304 (Not Modified)
告诉客户端能够继续使用缓存,不然返回200
从新获取新的资源。HTTP缓存早期的时候只有Expires和Last-Modified,为何后面又会出现Cache-Control和Etag呢?
先说说Expires和Cache-Control,Expires的值是一个准确的时间,比较的时候先根据返回头的Date值比较判断,可是若无Date头信息返回则是根据客户端的本地时间进行比较;本地时间由于各类因素影响,会存在各类不一样的值,致使Expires缓存的时间并非咱们想要的效果。而Cache-Control设置max-age使用的相对值则相对来讲控制粒度更精确了;而且Cache-Control的其余值则让咱们对于缓存的控制更加灵活。
再说说Last-Modified和Etag,Last-Modified的值也是一个准确的时间,精确到秒;使用时间来判断资源是否修改则可能存在如下问题:
针对以上的问题因此有了Etag的存在,Etag是根据资源内容生成的hash值对比判断资源是否更新,控制粒度比Last-Modified更加精确。
HTTP缓存的本质上是以空间换时间,缓存的存在是为了尽量的减小HTTP请求次数和HTTP传输的内容大小,这也是前端性能优化中重要的一环。合理的设置页面资源的缓存,有助你提高页面的体验。