什么是前端缓存?
前端缓存主要是分为HTTP缓存和浏览器缓存。其中HTTP缓存是在HTTP请求传输时用到的缓存,主要在服务器代码上设置;而浏览器缓存则主要由前端开发在前端js上进行设置。
缓存可以说是性能优化中简单高效的一种优化方式了。一个优秀的缓存策略可以缩短网页请求资源的距离,减少延迟,并且由于缓存文件可以重复利用,还可以减少带宽,降低网络负荷。
对于一个数据请求来说,可以分为发起网络请求、后端处理、浏览器响应三个步骤。浏览器缓存可以帮助我们在第一和第三步骤中优化性能。比如说直接使用缓存而不发起请求,或者发起了请求但后端存储的数据和前端一致,那么就没有必要再将数据回传回来,这样就减少了响应数据。
缓存过程分析
浏览器与服务器通信的方式为应答模式,即是:浏览器发起HTTP请求 ——服务器响应该请求。那么浏览器第一次向服务器发起该请求后拿到请求结果,会根据响应报文中HTTP头的缓存标识来决定是否缓存结果,如果是,则将请求结果和缓存标识存入浏览器缓存中,简单的过程如下图:
前端缓存之HTTP缓存
一.什么是HTTP缓存 ?
http缓存指的是: 当客户端向服务器请求资源时,会先抵达浏览器缓存,如果浏览器有“要请求资源”的副本,就可以直接从浏览器缓存中提取而不是从原始服务器中提取这个资源。
常见的http缓存只能缓存get请求响应的资源,对于其他类型的响应则无能为力,所以后续说的请求缓存都是指GET请求。
http缓存都是从第二次请求开始的。
第一次请求资源时,服务器返回资源,并在respone header头中回传资源的缓存参数;第二次请求时,浏览器判断这些请求参数。
- 命中强缓存则返回200。
- 否则就把请求参数加到request header头中传给服务器,看是否命中协商缓存。
• 命中则返回304。
• 否则服务器会返回200和新的资源。
二.http缓存的分类:
根据是否需要重新向服务器发起请求来分类,可分为:强制缓存/协商缓存 。
• 强制缓存如果生效,不需要再和服务器发生交互
• 协商缓存不管是否生效,都需要与服务端发生交互。
下面是强制缓存和协商缓存的一些对比:
下面将详细讲解两种缓存机制的工作原理
三. 强制缓存
1. 什么是强制缓存?
强制缓存就是向浏览器缓存查找该请求结果,并根据该结果的缓存规则来决定是否使用该缓存结果的过程。
2. 强制缓存可能出现的情况(三种)
①不存在该缓存结果和缓存标识,强制缓存失效,则直接向服务器发起请求(跟第一次发起请求一致),如下图:
②存在该缓存结果和缓存标识,但该结果已失效,强制缓存失效,则使用协商缓存,如下图
③存在该缓存结果和缓存标识,且该结果尚未失效,强制缓存生效,直接返回该结果,如下图
3.强制缓存的缓存规则是什么?
当浏览器向服务器发起请求时,服务器会将缓存规则放入HTTP响应报文的HTTP头中和请求结果一起返回给浏览器,控制强制缓存的字段分别是:
• Expires
• Cache-Control
(优先级:Cache-Control>Expires)
• Expires
Expires是HTTP/1.0控制网页缓存的字段,其值为服务器返回该请求结果缓存的到期时间,即再次发起该请求时,如果客户端的时间小于Expires的值时,直接使用缓存结果。
到了HTTP/1.1,Expire已经被Cache-Control替代,原因在于Expires控制缓存的原理是使用客户端的时间与服务端返回的时间做对比,那么如果客户端与服务端的时间因为某些原因(例如时区不同;客户端和服务端有一方的时间不准确)发生误差,那么强制缓存则会直接失效,这样的话强制缓存的存在则毫无意义。
• Cache-Control
在HTTP/1.1中,Cache-Control是最重要的规则,主要用于控制网页缓存,主要取值为:
(1)public:所有内容都将被缓存(客户端和代理服务器都可缓存)。
(2)private:所有内容只有客户端可以缓存,Cache-Control的默认取值。
(3)no-cache:客户端缓存内容,但是是否使用缓存则需要经过协商缓存来验证决定。
(4)no-store:所有内容都不会被缓存,即不使用强制缓存,也不使用协商缓存 。
(5)max-age=xxx (xxx is numeric):缓存内容将在xxx秒后失效。
接下来,我们通过一个例子来比较下Expires和Cache-Control有什么区别:
由上面的例子我们可以知道:
①HTTP响应报文中expires的时间值,是一个绝对值
②HTTP响应报文中Cache-Control为max-age=600,是相对值
在无法确定客户端的时间是否与服务端的时间同步的情况下(例如时区不同),Cache-Control相比于expires是更好的选择,所以同时存在时,只有Cache-Control生效。
4.强制缓存的缓存存放位置
当chrome浏览器返回200的状态码时,表示使用强制缓存,此时会有以下两种情况:
内存缓存(from memory cache):速度快和时间限制。 (从内存中获取:一般缓存更新频率较高的js、图片、字体等资源)
硬盘缓存(from disk cache):读取复杂,速度比内存缓存慢。
(从磁盘中获取:一般缓存更新频率较低的js、css等资源)
浏览器读取缓存的顺序为memory –> disk –> 服务器请求。
注意:这两种情况是chrome自身的一种缓存策略,这也是为什么chrome浏览器响应的快的原因。其他浏览器返回的是“已缓存”状态,而不会标识是从内存还是磁盘内获取的缓存。具体例子如下:
chrome浏览器:
Firefox浏览器:
四 .协商缓存
1. 什么是协商缓存?
协商缓存就是强制缓存失效后,浏览器携带缓存标识向服务器发起请求,由服务器根据缓存标识决定是否使用缓存的过程。
2. 协商缓存可能出现的情况(两种)
主要有以下两种情况:
①资源无更新,协商缓存生效,返回304,如下图所示:
②资源更新了,协商缓存失效,返回200和请求结果,如下图所示:
3.协商缓存的缓存规则是什么?
与强制缓存一样,协商缓存的标识也是在响应报文的HTTP头中和请求结果一起返回给浏览器的,控制协商缓存的字段分别是:
• Last-Modified / If-Modified-Since
• Etag / If-None-Match
(优先级:Etag / If-None-Match>Last-Modified / If-Modified-Since)
• Last-Modified / If-Modified-Since
Last-Modified是服务器响应请求时,返回该资源文件在服务器最后被修改的时间。 If-Modified-Since则是客户端再次发起该请求时,携带上次请求返回的Last-Modified值,通过此字段值告诉服务器该资源上次请求返回的最后被修改时间。
服务器收到该请求,发现请求头含有If-Modified-Since字段,则会根据If-Modified-Since的字段值与该资源在服务器的最后被修改时间做对比,若服务器的资源最后被修改时间大于If-Modified-Since的字段值,则重新返回资源,状态码为200;否则则返回304,代表资源无更新,可继续使用缓存文件。
• Etag / If-None-Match
Etag是服务器响应请求时,返回当前资源文件的一个唯一标识(由服务器生成)。If-None-Match是客户端再次发起该请求时,携带上次请求返回的唯一标识Etag值,通过此字段值告诉服务器该资源上次请求返回的唯一标识值。
服务器收到该请求后,发现该请求头中含有If-None-Match,则会根据If-None-Match的字段值与该资源在服务器的Etag值做对比。一致则返回状态码304,代表资源无更新,继续使用缓存文件。不一致则重新返回资源文件和状态码200。
注意:对于协商缓存,使用 Ctrl+F5强制刷新可以使得缓存无效。但是对于强缓存,在未过期时,必须更新资源路径才能发起新的请求(更改了路径相当于是另一个资源了,这也是前端工程化中常用到的技巧)。
对HTTP缓存之总结:
强制缓存优先于协商缓存进行,若强制缓存(Expires和Cache-Control)生效则直接使用缓存,若不生效则进行协商缓存(Last-Modified / If-Modified-Since和Etag / If-None-Match)。协商缓存由服务器决定是否使用缓存,若协商缓存失效,那么代表该请求的缓存失效,重新获取请求结果和状态码200,再存入浏览器缓存中;生效则返回304,继续使用缓存,主要过程如下:
本文大部分内容总结自以下两篇文章,如有遗漏作者请与本人联系。
https://www.jianshu.com/p/256d0873c398(简书)
https://www.jianshu.com/p/227cee9c8d15(简书)