浅析浏览器缓存机制

目录

1.浏览器缓存到底在哪

2. 浏览器缓存过程

3.缓存的种类

浅析浏览器缓存机制一文最后总结:

关于首次进入页面 浏览器缓存机制该如何运行

关于HTTP缓存决策指南


1.浏览器缓存到底在哪

首先了解 内存缓存(from memory cache)和硬盘缓存(from disk cache)的区别。

a)内存缓存(from memory cache): 具有快速读取和时效性。

    快速读取:内存缓存会将编译解析后的文件直接存入该进程的内存中,占据该进程的一定的内存资源,以方便下次运行使用时的快速读取。

    时效性:一旦该进程关闭,则该进程的内存则会清空。

b)硬盘缓存(from disk cache): 直接将缓存写入硬盘文件中,读取缓存需要对该缓存存放的硬盘文件进行I/O操作,然后重新解析该缓存内容,读取复杂,速度比内存缓存慢。

 浏览器缓存的存储地点分为两个。js和图片等文件会在解析执行后直接存入内存缓存中,而css文件则会存入硬盘缓存中。

2. 浏览器缓存过程

3.缓存的种类

a) 强缓存

    浏览器在加载资源时,会先根据本地缓存资源的 header 头(expires 和 cahe-control)中的信息判断是否命中强缓存,如果命中则直接使用缓存中的资源不会再向服务器发送请求,会直接从缓存中读取资源。请求返回200状态码,在chrome控制台的network选项中可以看到size显示from disk cache或from memory cache。

Expires和Cache-Control两者对比

1.Expires是HTTP1.0中的响应头

2.Cache-Control是HTTP1.1中的响应头

3.Cache-Control使用的是相对时间

4.Expires使用的是具体的过期日期而不是秒数,因为很多服务器跟客户端存在时钟不一致的情况,所以最好还是使用Cache-Control

5.Cache-Control和Expires,两者同时存在的话,Cache-Control优先级高于Expires

Cache-Control常用字段:

no-cache:需要进行协商缓存,发送请求到服务器确认是否使用缓存。

no-store:禁止使用缓存,每一次都要重新请求数据。

public:可以被所有的用户缓存,包括终端用户和 CDN 等中间代理服务器。

private:只能被终端用户的浏览器缓存,不允许 CDN 等中继缓存服务器对其缓存。

b) 协商缓存

    当强缓存没有命中的时候,浏览器会发送一个请求到服务器,服务器根据 header 中的部分信息来判断是否命中缓存。如果命中,则返回 304 ,告诉浏览器资源未更新,可使用本地的缓存。

Last-Modify/If-Modify-Since 和 ETag/If-None-Match两者对比

1.精确度上,Etag要优于Last-Modified,Last-Modified的时间单位是秒,如果某个文件在1秒内改变了多次,那么他们的Last-Modified其实并没有体现出来修改,但是Etag每次都会改变确保了精度;如果是负载均衡的服务器,各个服务器生成的Last-Modified也有可能不一致。

2.性能上,Etag要逊于Last-Modified,毕竟Last-Modified只需要记录时间,而Etag需要服务器通过算法来计算出一个hash值

3.Last-Modified 与 ETag 是可以一起使用的,服务器会优先验证 ETag,一致的情况下,才会继续比对 Last-Modified,最后才决定是否返回 304。

Last-Modify/If-Modify-Since

浏览器在第一次访问资源时,服务器返回资源的同时,在response header中添加 Last-Modified的header,值是这个资源在服务器上的最后修改时间,浏览器接收后缓存文件和header;

浏览器下一次请求这个资源,浏览器检测到有 Last-Modified这个header,于是添加If-Modified-Since这个header,值就是Last-Modified中的值;服务器再次收到这个资源请求,会根据 If-Modified-Since 中的值与服务器中这个资源的最后修改时间对比,如果没有变化,返回304和空的响应体,直接从缓存读取,如果If-Modified-Since的时间小于服务器中这个资源的最后修改时间,说明文件有更新,于是返回新的资源文件和200

缺点:

1.短时间内资源发生了改变,Last-Modified 并不会发生变化。

2.周期性变化。如果这个资源在一个周期内修改回原来的样子了,我们认为是可以使用缓存的,但是 Last-Modified 可不这样认为,因此便有了 ETag。

ETag/If-None-Match

Etag是上一次加载资源时,服务器返回的response header,是对该资源的一种唯一标识,只要资源有变化,Etag就会重新生成。浏览器在下一次加载资源向服务器发送请求时,会将上一次返回的Etag值放到request header里的If-None-Match里,服务器只需要比较客户端传来的If-None-Match跟自己服务器上该资源的ETag是否一致,就能很好地判断资源相对客户端而言是否被修改过了。如果服务器发现ETag匹配不上,那么直接以常规GET 200回包形式将新的资源(当然也包括了新的ETag)发给客户端;如果ETag是一致的,则直接返回304知会客户端直接使用本地缓存即可。

两种缓存的总结:

    1.看看是否命中强缓存,如果命中,就直接使用缓存了。

    2.如果没有命中强缓存,就发请求到服务器检查是否命中协商缓存。

    3.如果命中协商缓存,服务器会返回 304 告诉浏览器使用本地缓存。

    4.否则,返回最新的资源。

浅析浏览器缓存机制一文最后总结:

  • 浏览器端缓存分为200 from cache和304 not modified
  • HTTP协议中Cache-Control 和 Expires可以用来设置新鲜度的限值,前者是HTTP1.1中新增的响应头,后者是HTTP1.0中的响应头。
  • max-age(单位为s)而Expires指定的是具体的过期日期而不是秒数
  • Cache-Control和Expires同时使用的话,Cache-Control会覆盖Expires
  • 客户端不用关心ETag值如何产生,只要服务在资源状态发生变更的情况下将ETag值发送给它就行
  • Apache默认通过FileEtag中FileEtag INode Mtime Size的配置自动生成ETag(当然也可以通过用户自定义的方式)。
  • ETag常与If-None-Match或者If-Match一起,由客户端通过HTTP头信息(包括ETag值)发送给服务端处理。
  • Last-Modified常与If-Modified-Since一起由客户端将Last-Modified值包括在HTTP头信息中发给服务端进行处理。
  • 有些文档资源周期性的被重写,但实际内容没有改变。此时文件元数据中会显示文件最近的修改日期与If-Modified-Since不相同,导致不必要的响应。

关于首次进入页面 浏览器缓存机制该如何运行

首先我们要了解Expires 和 Cache-Control 是响应头,也就是说是接口返回的,会根据响应报文中HTTP头的缓存标识,决定是否缓存结果,是否将请求结果和缓存标识存入浏览器缓存中。也就是说,当我们第一次进入接口的时候,是不会去查询缓存的,因为该接口是没有本地有缓存标识的。

关于HTTP缓存决策指南

 

 这张流程图可解答为:

当我们的资源内容不可复用时,直接为 Cache-Control 设置 no-store,拒绝一切形式的缓存;否则考虑是否每次都需要向服务器进行缓存有效确认,如果需要,那么设 Cache-Control 的值为 no-cache;否则考虑该资源是否可以被代理服务器缓存,根据其结果决定是设置为 private 还是 public;然后考虑该资源的过期时间,设置对应的 max-age 和 s-maxage 值;最后,配置协商缓存需要用到的 Etag、Last-Modified 等参数。

感谢下列博客,如有冒犯可联系删除

前端必须要懂的浏览器缓存机制 - 牧云流 - 博客园

浏览器缓存原理以及本地存储 - SegmentFault 思否

实践这一次,彻底搞懂浏览器缓存机制 - SegmentFault 思否

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值