酒浓码浓 - 强缓存、协商缓存的区别

强缓存、协商缓存的区别

浏览器缓存在前端性能优化是个非常重要的点,奈何小编没文化,只能卧槽形容它。

卧槽,让我们首先来思考一波向服务器发起请求资源时,浏览器是怎么个处理过程呢。

宏观的解析过程我们就不深入的探讨,下文仅对缓存这块,以chrome为例着重卧槽:

如果我们在做项目时对Network仔细的观察就会发现有很多些细微的区别

以上的例子,我们可以发现强缓存(200,from cache), 与协商缓存(304),与正常请求的(200)呈现颜色以及报文都不一样。

from memory cache 是读的内存

from disk cache 是读的磁盘

强缓存:from cache,当发起资源请求时,如果缓存的某些请求头信息没过期就直接读取缓存,不发起请求,直接拿cache里的缓存资源。OK,那么不必发起请求,所以请求时间为0ms。在性能的速度方面我们可以看到其显著的好处。

协商缓存:304或黑色200,在强缓存没命中的时候,向服务器发起请求,根据响应头的某些信息得知浏览器缓存的资源与服务器的资源一不一致?若一致仅返回个请求头,状态码为304,是我们前端性能优化必懂的一个状态码。如果不一致请求这份资源。成功了就是黑色的200状态码,返回的是一个资源文件。

针对缓存的重要性,我们可以很明显的看到同一页面第一次请求,与有缓存资源时的加载时间对比


ok,那我们进一步的去了解,请求头中的哪些属性影响着以上卧槽。下图为例:

当浏览器请求时会先获取请求头的信息

第一次请求,浏览器通过请求头携带Expires,Cache-Control,Last-Modified/Etag向服务器请求,此时服务器记录第一次请求的Last-Modified/Etag,并返回资源。


当浏览器再次请求的时候依照原理先看内存再看磁盘再走网络资源请求:

网络资源请求优先级判断 cache-control(expires会被前者max-age覆盖掉) > etag > last-modified

既然了解了其好处,我们就要针对某些资源做处理(如node,tomcat、nginx等):

res.setHeader('max-age': '3600 public immutable') immutable即使过了3600也不会向浏览器发请求
res.setHeader(etag: '5c20abbd-e2e8')
res.setHeader('last-modified': Mon, 20 Dec 2019 18:22:00 GMT)

或者

<meta HTTP-EQUIV="Pragma" CONTENT="no-cache">

HTTP1.0中主要使用header里的If-Modified-Since,Expires来做为缓存判断的标准
HTTP1.1则引入了更多的缓存控制策略例如Entity tag,If-Unmodified-Since, If-Match, If-None-Match等更多可供选择的缓存头来控制缓存策略。

Cache-Control

Cache-Control:Public    可以被任何缓存所缓存,多用户间共享(包括终端用户和CDN等中间代理服务器)

Cache-Control:Private   内容只缓存到私有缓存中,不能在用户间共享(不允许CDN等中继缓存服务器对其缓存)

Cache-Control:no-cache   不使用强缓存。强制服务器来验证使用协商缓存或重新请求。先与服务器确认返回的响应是否被更改,如果之前的响应中存在ETag,那么请求的时候会与服务端验证,如果资源未被更改,则可以避免重新下载

Cache-Control:no-store:强制禁止客户端、服务器端的缓存。每次都要请求新的资源。

Cache-Control: max-age=number:缓存时间 以秒为单位,源第一次的请求时间和max-age值计算出一个资源过期时间,再拿这个过期时间跟当前的请求时间比较。与Expires相反,时间是相对于请求的时间。

Cache-Control: max-stale=number:表明客户端愿意接收一个已经过期的资源。表示响应不能已经过时超过设置的秒数。

如果设置的时间后面加个,immutable那就表示该资源永远不会过期,不会向服务器发送请求。 

Pargma: no-cache

防止页面被缓存, 在HTTP/1.1版本中,它和Cache-Control:no-cache作用一模一样

Expires

这个名字我们应该不陌生,生存期,它声明一个时间,如果超过了这个时间就会请求服务器。
有时候仅仅设置Pragma: no-cache Cache-Control: no-cache 还是不保险,需要将过期时间设置成过去的时间就确保了对象不被缓存

Last-Modified

资源的最后修改时间。

Etag

Etag粗暴的理解为服务器上修改某资源就会打个tag记录下来,用途与Last-Modified一样,判断此次tag与上次一不一样。于是就有人问了为什么还要Last-Modified,If-Modified-Since能检查到的颗粒度是秒,如果二人同时修改文件提交,那就相当于在1S内修改了2次资源发生碰撞就出错了。所以和Last-Modified一起使用,加强服务器判断的准确度。

If-Modified-Since

浏览器端缓存页面的最后修改时间,发送请求时会与服务器资源的最后修改时间进行对比。如果时间一致,那么返回304,客户端就直接使用本地缓存文件。如果时间不一致,就会返回200和新的文件内容。客户端接到之后,会丢弃旧文件,把新文件缓存起来,并显示在浏览器中。

If-None-Match

和ETag一起工作,工作原理是在HTTP Response中添加ETag信息。 当用户再次请求该资源时,将在HTTP Request 中加入If-None-Match信息(ETag的值)。如果服务器验证资源的ETag没有改变(该资源没有更新),将返回一个304状态告诉客户端使用本地缓存文件。否则将返回200状态和新的资源和Etag。

HTTP官方文档: https://developer.mozilla.org/zh-CN/docs/Web/HTTP

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值