http强缓存、协商缓存的区别

1、浏览器缓存


浏览器缓存是浏览器将用户请求过的静态资源(html、css、js),存储到电脑本地磁盘中,当浏览器再次访问时,就可以直接从本地加载了,不需要再去服务端请求了。

缓存的优点:

  • 减少了不必要的数据传输,节省带宽
  • 减少服务器的负担,提升网站性能
  • 加快了客户端加载网页的速度
  • 用户体验友好

缺点:

  • 资源如果有更改但是客户端不及时更新会造成用户获取信息滞后。

 

2、缓存流程


缓存流程分为两种情况,浏览器第一次请求和后续请求。

浏览器第一次请求:

上述的缓存规则,就是声明所请求的这个资源,要采取哪种缓存策略?缓存多长时间?等。

这个规则,是在http的 response header 中返回来的。

                                          

浏览器后续请求

                                      

 从上图可以知道,浏览器缓存包含两种类型,即强缓存(也叫本地缓存)和协商缓存,浏览器在第一次请求发生后,再次请求时:

  • 浏览器在请求某一资源时,会先获取该资源缓存的header信息,判断是否命中强缓存(是否有cache-control和expires信息),若命中则根据cache-control的max-age属性判断是否过期,没有过期直接从缓存中获取资源信息,包括缓存header信息;本次请求根本就不会与服务器进行通信;
  • 如果没有命中强缓存,或缓存过期。浏览器会发送请求到服务器,请求会携带第一次请求返回的有关缓存的header字段信息(Last-Modified/If-Modified-Since和Etag/If-None-Match),由服务器根据请求中的相关header信息来比对结果是否协商缓存命中;若命中(requst header返回的If-None-Match和If-Modified-Since与服务器的Etag和Last-Modified相同),则服务器返回新的响应header信息更新缓存中的对应header信息,但是并不返回资源内容,它会告知浏览器可以直接从缓存获取;否则返回最新的资源内容

 

 

3、缓存规则


强缓存和协商缓存。

 

强缓存

直接从缓存中获取资源而不经过服务器,前提是资源没过期。

即如果资源没过期,就取缓存,如果过期了,则请求服务器。

如何判断资源是否过期呢,也就是说强缓存的规则怎么看?

 

主要是看 response headers 中的 Cache-Control 的值,图中的max-age = 31xxxxxxx,就是说在这些秒内,都直接使用缓存,超过了就继续请求服务器

而和 Cache-Control 并列的,还有一个 Expires ,已经基本淘汰了,所以不用管

Cache-Control 的几个取值含义:

  • max-age=xxx: 过期时间(重要)
  • no-cache:不使用强缓存(本地缓存)。需要使用缓存协商,先与服务器确认返回的响应是否被更改,如果之前的响应中存在ETag,那么请求的时候会与服务端验证,如果资源未被更改,则可以避免重新下载。(重要)
  • no-store:不强缓存,也不协商缓存。直接禁止游览器缓存数据,每次用户请求该资源,都会向服务器发送一个请求,每次都会下载完整的资源。
  • public:浏览器和CDN等中间代理服务器都可以缓存
  • private:仅浏览器缓存,不允许CDN等中继缓存服务器对其缓存。(对于private和public,前端可以认为一样,不用深究)

  注意:如果cache-control与expires同时存在的话,cache-control的优先级高于expires

所以,对于强缓存,我们主要研究 Cache-Control 中的 max-age 和 no-cache

所以,判断该资源是否命中强缓存,就看 response 中 Cache-Control 的值,如果有max-age=xxx秒,则命中强缓存。如果Cache-Control的值是no-cache,说明没命中强缓存,走协商缓存。

 

强缓存流程:

                      

 

 

                        

 

所以强缓存步骤:

  1. 第一次请求 a.js ,缓存表中没该信息,直接请求后端服务器。
  2. 后端服务器返回了 a.js ,且 http response header 中 cache-control 为 max-age=xxxx,所以是强缓存规则,存入缓存表中。
  3. 第二次请求 a.js ,缓存表中是 max-age, 那么命中强缓存,然后判断是否过期,如果没过期,直接读缓存的a.js,如果过期了,则执行协商缓存的步骤了。

 

缓存保存的位置

缓存有内存缓存和硬盘缓存两种

  • 内存缓存(from memory cache):内存缓存具有两个特点,分别是快速读取和时效性;
  • 快速读取:内存缓存会将编译解析后的文件,直接存入该进程的内存中,占据该进程一定的内存资源,以方便下次运行使用时的快速读取。
  • 时效性:一旦该进程关闭,则该进程的内存则会清空。
  • 硬盘缓存(from disk cache):硬盘缓存则是直接将缓存写入硬盘文件中,读取缓存需要对该缓存存放的硬盘文件进行I/O操作,然后重新解析该缓存内容,读取复杂,速度比内存缓存慢。

在浏览器中,浏览器会在js和图片等文件解析执行后直接存入内存缓存中,那么当刷新页面时只需直接从内存缓存中读取(from memory cache);而css文件则会存入硬盘文件中,所以每次渲染页面都需要从硬盘读取缓存(from disk cache)。


 

协商缓存

触发条件:

  1. Cache-Control 的值为 no-cache (不强缓存)
  2. 或者 max-age 过期了 (强缓存,但总有过期的时候)

也就是说,不管怎样,都可能最后要进行协商缓存(no-store除外)

                                              

 

这个图,虽然强缓存命中,但是也有 ETag 和 Last-Modified ,这两个就是协商缓存的相关规则。虽然之前的强缓存流程和他俩没关。。。

ETag:每个文件有一个,改动文件了就变了,可以看似md5

Last-Modified:文件的修改时间

也就是说,每次http返回来 response header 中的 ETag和 Last-Modified,在下次请求时在 request header 就把这两个带上(但是名字变了ETag-->If-None-Match,Last-Modified-->If-Modified-Since ),服务端把你带过来的标识,资源目前的标识,进行对比,然后判断资源是否更改了。

这个过程是循环往复的,即缓存表在每次请求成功后都会更新规则。

1. 第n次请求成功时:

                                               

 

2. 缓存表中更新该资源的 ETag 值

3. 第n+1次请求:

从缓存表中取该资源最新的ETag,然后加在 request header 中, 注意变名字了,由 ETag -- > If-None-Match

                        

 

 

图:

                      

 

 

                          

 

所以协商缓存步骤总结:

  1. 请求资源时,把用户本地该资源的 ETag 同时带到服务端,服务端和最新资源做对比。
  2. 如果资源没更改,返回304码(携带header信息),浏览器读取本地缓存。
  3. 如果资源有更改,返回200码(携带body数据),返回最新的资源。

 

4、其他


1. 为什么要有Etag

你可能会觉得使用Last-Modified已经足以让浏览器知道本地的缓存副本是否足够新,为什么还需要Etag呢?HTTP1.1中Etag的出现(也就是说,ETag是新增的,为了解决之前只有If-Modified的缺点)主要是为了解决几个Last-Modified比较难解决的问题:

  • 一些文件也许会周期性的更改,但是他的内容并不改变(仅仅改变的修改时间),这个时候我们并不希望客户端认为这个文件被修改了,而重新GET;

  • 某些文件修改非常频繁,比如在秒以下的时间内进行修改,(比方说1s内修改了N次),If-Modified-Since能检查到的粒度是s级的,这种修改无法判断(或者说UNIX记录MTIME只能精确到秒);

  • 某些服务器不能精确的得到文件的最后修改时间。

2. 强缓存与协商缓存的区别可以用下表来表示:

 

3. 用户行为对缓存的影响

 

即:F5 会 跳过强缓存规则,直接走协商缓存;;;Ctrl+F5 ,跳过所有缓存规则,和第一次请求一样,重新获取资源

 

5、总结


 

                        

 

 

                     

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值