HTTP缓存和浏览器的本地存储

本地存储:https://www.jianshu.com/p/ed6ca541a321

HTTP缓存:https://www.jianshu.com/p/be6c3ae61b51

在介绍HTTP缓存之前,先介绍一下HTTP报文

  • HTTP报文就是浏览器和服务器之间通信时发送及响应的数据块
  • 浏览器向服务器请求数据,发送request;服务器向浏览器返回数据,返回response
  1. 包含属性的首部header ------ 附加信息(cookie, 缓存信息....)与缓存相关的规则信息,都包含在header中
  2. 包含数据的主体部分(body) --- HTTP请求想要传输的部分

1.HTTP缓存

  • http请求做为影响前端性能极为重要的一环,因为请求受网络影响很大,如果网络很慢的情况下,页面很可能会空白很久。对于首次进入网站的用户可能要通过优化接口性能和接口数量来解决。但是,对于重复进入页面的用户,除了浏览器缓存,http缓存可以很大程度对已经加载过的页面进行优化。

  • 浏览器缓存就是把一个已经请求过的web资源(html, js, css,图片...)拷贝一份副本存储到浏览器中。缓存会根据进来的请求保存输出内容的副本。当下一个请求来到的时候,如果是相同的URL,缓存会根据缓存机制决定是直接使用副本响应访问请求,还是向源服务器再次发送请求(当然还有304的情况)。
    缓存是根据url来处理的,只要url不一样就是新的资源。

1.缓存位置

企业微信截图_15669847239824.png
  • service worker
  1. 是运行在浏览器背后的独立线程,一般可以用来实现缓存功能。如果使用service worker 传输协议一定需要https
  2. 自由控制缓存哪些文件,如何匹配缓存,如何读取缓存, 并且缓存时持续的
  • memery cache
  1. 也就是内存中的缓存,主要包含的是当前页面中已经抓取到的资源,比如css , js , 图片等等,虽然读取内存中的数据比磁盘快,内存缓存虽然去读高效,但是混村持续性很短,而且会随着进程的释放而释放,一旦关闭了这个页面,相应的内存中的缓存也会被释放
  2. 读取效率高,缓存持续性很短
  3. 需要注意的事情是,内存缓存在缓存资源时并不关心返回资源的HTTP缓存头Cache-Control是什么值,同时资源的匹配也并非仅仅是对URL做匹配,还可能会对Content-Type,CORS等其他特征做校验。
  • disk cache
  1. 存储在硬盘中的缓存,读取速度虽然慢点,但是什么都可以存放到磁盘中。
  2. 读取速度慢,但是和memery cache相比,胜在容量和存储的时效上
    浏览器会把哪些文件丢进内存中?哪些丢进硬盘中?
    对于大文件来说,大概率是不存储在内存中的,反之优先当前系统内存使用率高的话,文件优先存储进硬盘

  • push cache
  1. 推送缓存,是HTTP/2中的内容,当以上三种缓存都没有命中的时候,它才会被使用,只会出现在会话Session中,一旦会话结束就会被释放,而且缓存时间也很短暂,在chorm中大概只有5分钟左右,同时它也并非严格只想HTTP头中的缓存指令
  2. 所有的资源都能被推送,并且能够被缓存,但是 Edge 和 Safari 浏览器支持相对比较差
  3. 可以推送 no-cache 和 no-store 的资源
  4. 一旦连接被关闭,Push Cache 就被释放
  5. 多个页面可以使用同一个HTTP/2的连接,也就可以使用同一个Push Cache。这主要还是依赖浏览器的实现而定,出于对性能的考虑,有的浏览器会对相同域名但不同的tab标签使用同一个HTTP连接。
  6. Push Cache 中的缓存只能被使用一次
  7. 浏览器可以拒绝接受已经存在的资源推送,你可以给其他域名推送资源

缓存规则解析

客户端在第一次请求数据时,此时浏览器中没有对应的缓存数据,需要请求服务器,服务器返回后,将数据缓存到浏览器中



HTTP缓存有很多种规则,根据是否需要重新向服务器发送请求来分类,我们将其分为强缓存和协商缓存

对已存在缓存数据,仅基于强缓存,请求数据的流程:

image.png

对于已存在的缓存数据,仅基于协商缓存,请求数据的流程:


image.png

如果强缓存生效,则不需要在和服务器交互,而协商缓存不管是否生效都需要与服务器交互。者两种缓存规则时可以同时存在的,但是强缓存优先级高于协商缓存,也就是说当执行强缓存时如果缓存生效,则不再只想协商缓存的规则

强缓存

浏览器在第一次访问接口之后的response headers里会携带一些字段,这些字段决定关于这个请求的缓存情况

  1. expires : 这是 http1.0的规范。
    1.1. 它的值为一个绝对使劲按的GMT格式的时间字符串。例如 Mon,10 Jun 2015 21:31:12 GMT,如果发送请求的时间在expires之前,那么本地缓存始终有效,否则就会发送请求到服务器来获取资源.
    1.2. 还有一个问题是,到期时间是服务器生成的,但是客户端时间可能和服务端时间有误差,这就会导致缓存命中的误差,所以在HTTP1.1的版本使用Cache-Control替代。

  2. cache-control : max-age = number 这是http1.1出现的header信息,主要是利用该字段的max-age值来进行判断,它是一个相对值,资源第一次的请求时间和Cache-Cotrol设定的有效期,计算出一个资源过期时间,再拿这个过期时间跟当前请求时间比较,如果请求时间在过期时间之前就会命中缓存,否则就不行
    2.1. no-cache : 直接禁止浏览器缓存数据,每次用户请求该资源,都会向服务器发送一个请求,每次都会下载完整的资源。
    2.2. public : 默认为private。可以被所有的用户缓存,包括终端用户和CDN等中间代理服务器
    2.3. private : 只能被终端用户的浏览器缓存,不允许CDN等中继缓存服务器对其缓存
    2.4. max-age=xxxx: 缓存的内容将在 xxx秒之后失效
    2.5. no-store: 所有内容都不缓存,强制缓存和对比缓存都不会触发

    image.png

    Cache-Control仅指定了max-age,所以默认为private,缓存时间为31536000秒(365天)也就是说,在365天内再次请求这条数据,都会直接获取缓存数据库中的数据,直接使用。

如果cache-control与expires同时存在的话cache-contol的优先级高于expires
强缓存时段命中,会直接从缓存中返回数据,返回200,这一段时间,不管接口内容有没有变化都不会进行请求更新

协商缓存

当没有强缓存时,会像服务器端寻求帮助,也即是问一下服务器有没有更改,向接口判断是否有缓存。如果命中协商缓存则返回304,并且本地返回缓存内容,如果没有命中,则重新发起请求.

image.png

可以看出,在协商缓存生效的时候,状态码是304,并且报文大小和请求时间大大减少。这是因为,服务器端在进行标识比价之后,只会返回header部分,通过状态码通知客户端使用缓存,不需要将报文主体部分返回给客户端。
对于协商缓存来说,缓存标识的传递时至关重要的,它在请求header和响应header间进行传递

协商缓存需要跟服务器端通过特殊标识链接,即第一次请求的响应头带上某个字段(Last-Modified / Etag),则后续请求会带上对应的请求字段(If-Modified-Since / if-None-Match),若响应头没有Last-Modified / Etag字段,则请求头也不会有对应字段

  1. Last-Modified / If-Modified-Since

    Last-Modified

    Last-Modified服务器在响应请求时,告诉浏览器资源的最后修改时间。
    If-Modified-Since

    If-Modified-Since:
    再次请求服务器时,通过此字段通知服务器上次请求时,服务器返回的资源最后修改时间。
    服务器收到请求后发现有头If-Modified-Since 则与被请求资源的最后修改时间进行比对。
    若资源的最后修改时间大于If-Modified-Since,说明资源又被改动过,则响应整片资源内容,返回状态码200;
    若资源的最后修改时间小于或等于If-Modified-Since,说明资源无新修改,则响应HTTP 304,告知浏览器继续使用所保存的cache。

  2. Etag / If-None-Match
    由服务器生成的每一个资源的唯一标识字符串,只要资源有变化这个值就会发生变化,其判断过程与Last-modified / If-Modified-Since类似,和Last-Modified不一样的是当服务器返回304的时候,由于ETag重新生成过,response header中还会把这个ETag返回,即使这个ETag和之前的没有变化

    Etag

    Etag 服务器响应请求时,告诉浏览器当前资源在服务器的唯一标识(生成规则由服务器决定)。

If-None-Match

If-None-Match再次请求服务器时,通过此字段通知服务器客户段缓存数据的唯一标识。
服务器收到请求后发现有头If-None-Match 则与被请求资源的唯一标识进行比对,
不同,说明资源又被改动过,则响应整片资源内容,返回状态码200;
相同,说明资源无新修改,则响应HTTP 304,告知浏览器继续使用所保存的cache。

image.png

既生Last-Modified何生Etag?
你可能会觉得使用Last-Modified已经足以让浏览器知道本地的缓存副本是否足够新,为什么还需要Etag(实体标识)呢?HTTP1.1中Etag的出现主要是为了解决几个Last-Modified比较难解决的问题:

  1. Last-Modified标注的最后修改只能精确到秒级,如果某些文件在1秒钟以内,被修改多次的话,它将不能准确标注文件的修改时间
  2. 如果某些文件会被定期生成,当有时内容并没有任何变化,但Last-Modified却改变了,导致文件没法使用缓存
    3.有可能存在服务器没有准确获取文件修改时间,或者与代理服务器时间不一致等情形
    Etag是服务器自动生成或者由开发者生成的对应资源在服务器端的唯一标识符,能够更加准确的控制缓存。Last-Modified与ETag是可以一起使用的,服务器会优先验证ETag,一致的情况下,才会继续比对Last-Modified,最后才决定是否返回304

用户操作对缓存的影响

参考文档:https://www.jianshu.com/p/54cc04190252

你可能感兴趣的:(HTTP缓存和浏览器的本地存储)