彻底明白http强缓存和协议缓存

我们整天和浏览器和打交道,应该都听过强缓存和协议缓存,强缓存和协商缓存(也有叫对比缓存)都是浏览器的缓存策略,需要先明确一点,既然是浏览器的缓存,缓存的数据都是存放于客户端的机子上的,只是根据优先级不同,存储位置不同,还可以进行细分而已,比如 Service Worker(代理缓存),Memory Cache(内存缓存),Disk Cache(磁盘缓存)!

1.浏览器如何缓存介绍

当我们打开一个页面时候,请求回来了html、css、js、图片等文件,会把这些文件储存在本地缓存中,当我们下次打开这个页面的时候,就可以直接从缓存中读取这些文件,不用再去服务器请求了!
优点:

  1. 减少不需要的网络传输,节省宽带
  2. 减少服务的负担,大大提高了网络性能
  3. 加快了客户端加载网页的速度
  4. 用户体验好

缺点:

  1. 如果资源更新,客户端还用缓存会造成用户获取不到最新的资源信息
2.浏览器缓存介绍
一.内存缓存(memory cache)

在这里插入图片描述
一般js文件,图片都储存在内存中,因为可能频繁要用到,所以内存中读取比较快!

特点:

  1. 快速读取(直接把文件存入进程内存中,占用该进程一定的内存资源,下次运行时可快速读取)
  2. 时效性(一旦结束进程,该进程的内存清空)
二.磁盘缓存(disk cache)

在这里插入图片描述
顾名思义就是储存在磁盘(电脑中),当下次访问的时候就不需要重新下载,直接从磁盘中读取!一般非脚本文件会储存在磁盘中(如css等),因为css只加载一次就渲染出来了,不会频繁读取他,想脚本文件,图片就不适合存在磁盘中,因为脚本文件可能随时执行(一个点击操作事件就触发脚本),如果放在磁盘中,还需要从磁盘取到内存中,这样就需要I/O操作(input读取,读到这个文件,output写入,然后拷贝到内存),这个过程比较慢了,很可能浏览器会失去响应!

特点:退出进程,数据不会清空

三.缓存优先级(三级缓存原理)
  1. 先从内存中查找,如果有,直接加载
  2. 如果没有,从磁盘中读取,直接加载
  3. 都没有的话,就请求网络获取资源
  4. 获取的资源缓存到内存和磁盘中

来操作一波看下面图:
在这里插入图片描述
以百度网站为例,第一次刷新,内存和磁盘都没有资源,去请求网络资源,当我刷新后,先去内存中找资源,找到了,显示状态200(from memory cache),然后我再关闭这个网页,重新打开百度网站,然后文件状态200(from disk cache)

3.浏览器缓存分类
一.强缓存

顾名思义强(强求)缓存,如果命中强缓存且未过期,那么直接读取缓存资源!这里有个条件是未过期!什么未过期?那就要引入head中两个属性expires和cache-control

expires
这个http 1.0规范,是个绝对时间 比如 Sat Aug 01 2020 16:13:03 GMT 好比你在超市买了瓶饮料,饮料瓶盖上会有个过期时间(2021,6,6),到了这个时间就过期了,不能喝了!(但是有些人可能不知道今天是几月几号,混日子过的?),看下图:

在这里插入图片描述
这里告诉浏览器这个文件到2030年 6月26 星期3 11点37份1秒(标准时间)才过期,没到这个时间,你都可以在缓存中取!

缺点:如果服务端的时间和客户端的时间不一致就会导致缓存混乱问题,所以http1.1中引入了cache-control

cache-control
这个http 1.1出现head的属性,看英文意思是缓存控制,它有几种形式:

  1. max-age=666 这个666就是过期时间(是个相对时间,过了666秒才过期)
  2. max-age=no-cache 不使用强缓存(本地缓存)。需要使用协商缓存(后面会讲)
  3. max-age=no-store 这个才是真正的不使用缓存(强缓存,协商缓存),每次请求资源都会发送请求来获取资源
  4. max-age=public 可以被所有用户缓存,包括浏览器终端用户和CDN等中间代理服务器
  5. max-age=private 只能被浏览器终端用户缓存,不允许CDN等中间代理服务器对其缓存

看下图:
在这里插入图片描述

如果cache-control与expires同时存在的话,cache-control的优先级高于expires!
看下强缓存的执行流程:

在这里插入图片描述
在这里插入图片描述

二.协商缓存

顾名思义就是要协商下(要和服务器商量下),如果服务器同意了,我就用本地缓存,如果不同意,那没办法,乖乖请求最新的资源回来,接下来要引入两个属性 ETag 和 Last-Modified

Last-Modified
最后的修改时间,当我们第一次去发送请求后,服务器会再响应头里面带上这个文件的Last-Modified,当我们再次请求这个文件时候,会在请求头里面带上If-Modified-Since(就是之前响应头的Last-Modified,只是名字变了),如果两个时间相同就说明这个文件没有改过!那么用本地缓存吧!如果时间不对,还是乖乖请求最新的资源回来吧!看下图:
在这里插入图片描述
看下请求的状态(304):
在这里插入图片描述

这里请求头中的文件和响应头的时间一样的,所以读取本地缓存,服务器返回的状态是304(注意协商缓存需要和服务器打下交道,把时间传过去,服务器对比时间,如果相同用缓存,不会返回内容)

缺点: 比如在秒以下的时间内进行修改,(比方说1s内修改了N次),If-Modified-Since能检查到的是s级的,或者某些服务器不能精确的得到文件的最后修改时间,又或者一些文件只是修改了时间并没有改变内容,这个时候我们并不希望客户端认为这个文件被修改了,而重新去请求新资源!这些Last-Modified是无法判断的,那么就引入了ETag

ETag
你可以把它看成md5戳,每个文件都有个,如果文件改了那么这个md5值也改变了(文件的唯一标识)
操作流程和Last-Modified类似的!

缺点:每次客户端发出请求,服务端都会根据资源重新生成一个Etag,对性能有影响,可能会给服务器带来更大的负担

有时候会两个一起用,每次请求文件,每次http返回来 response header 中的 ETag和 Last-Modified,在下次请求时在 request header 就把这两个带上(但是名字变了ETag–>If-None-Match,Last-Modified–>If-Modified-Since ),服务端把你带过来的标识和资源目前的标识进行对比,然后判断资是否返回状态304还是200(请求最新资源)!看下图:

在这里插入图片描述
在这里插入图片描述

如果浏览器访问之前已经访问的资源,我们来总结下流程:

  1. 先看是否命中强缓存个,如果命中了,直接读取本地缓存资源(状态200 from memory cache | from dick cache)
  2. 如果没有命中强缓存,默认走协商缓存(并不是一定命中)!
  3. 发送上次响应头返回的数据到服务端,服务端判断是否命中协商缓存 ,如果命中了,直接读取本地缓存资源(状态304 No Modified)
  4. 如果没命中,直接请求最新资源(状态200)
4.补充

cache-control在请求头和响应头的含义不一样,拿cache-control:max-age =no-cache来说吧!

请求头:表示浏览器不读取缓存,直接发送请求获取最新资源
响应头:表示不使用强缓存,默认使用协商缓存。

所以为什么 ctrl+F5可以跳过强缓存和协商缓存,看下图:
在这里插入图片描述
最后总结下用户操作对浏览器缓存的影响

地址回车 | 页面跳转链接 | 新打开窗口 | 回退 | 前进 这些操作对强缓存和协商缓存都有效! F5刷新会跳过强缓存,对协商缓存有效! ctrl+F5对对强缓存和协商缓存无效!

参考文献:

  1. http强缓存、协商缓存的区别
  2. 实践这一次,搞懂浏览器缓存机制
  3. 图解Http缓存控制之max-age=0、no-cache、no-store区别
  • 10
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值