一.缓存位置
从缓存的位置上浏览器一般分 内存缓存(Memory Cache),磁盘缓存(Disk Cache)
1.Memory Cache:
也即内存中的缓存,主要包含的是当前中页面中已经抓取到的资源,例如页面上已经下载的样式、脚本、图片等。读取内存中的数据肯定比磁盘快,内存缓存虽然读取高效,可是缓存持续性很短,会随着进程的释放而释放。 一旦我们关闭 Tab 页面,内存中的缓存也就被释放了,时效性有限。
那么既然内存缓存这么高效,我们是不是能让数据都存放在内存中呢?
这是不可能的。计算机中的内存一定比硬盘容量小得多,操作系统需要精打细算内存的使用,所以能让我们使用的内存必然不多。
200 form memory cache : 当我们访问过页面以后,再次刷新页面,不访问服务器,一般已经加载过该资源且缓存在了内存当中,直接从内存中读取缓存。浏览器关闭后,数据将不存在(资源被释放掉了),再次打开相同的页面时,不会出现from memory cache。
2. Disk Cache:
Disk Cache 也就是存储在硬盘中的缓存,读取速度慢点,但是什么都能存储到磁盘中,比之 Memory Cache 胜在容量和存储时效性上。
在所有浏览器缓存中,Disk Cache 覆盖面基本是最大的。它会根据 HTTP Herder 中的字段判断哪些资源需要缓存,哪些资源可以不请求直接使用,哪些资源已经过期需要重新请求。并且即使在跨站点的情况下,相同地址的资源一旦被硬盘缓存下来,就不会再次去请求数据。绝大部分的缓存都来自 Disk Cache。
浏览器会把哪些文件丢进内存中?哪些丢进硬盘中?
关于这点,网上说法不一,不过以下观点比较靠得住:
- 对于大文件来说,大概率是不存储在内存中的,反之优先
- 当前系统内存使用率高的话,文件优先存储进硬盘
200 form memory cache : 当我们访问过页面以后, 关闭页面后后再次打开 ,不访问服务器,已经在之前的某个时间加载过该资源,直接从硬盘中读取缓存,关闭浏览器后,数据依然存在,此资源不会随着该页面的关闭而释放掉下次打开仍然会是from disk cache。
二.缓存过程
由上图我们可以知道:
-
浏览器每次发起请求,都会先在浏览器缓存中查找该请求的结果以及缓存标识
-
浏览器每次拿到返回的请求结果都会将该结果和缓存标识存入浏览器缓存
根据是 是否向浏览器发请求,浏览器缓存一般分为 强制缓存 和协商缓存;
三. 强制缓存
强缓存:不会向服务器发送请求,直接从缓存中读取资源,在chrome控制台的Network选项中可以看到该请求返回200的状态码,并且Size显示from disk cache或from memory cache。强缓存可以通过设置两种 HTTP Header 实现:Expires 和 Cache-Control。
1.Expires
expires 是http1.0 的产物, 指的是 资源时效的绝对时间,如果改了本地的时间,会影响资源的有效性;
2.Cache-Control
在HTTP/1.1中, 添加 Cache-Control ,优先级高于 expires,cache-comtrol 有以下取值:
max-age:设置资源能被缓存 的相对时间,相对发送的request时间, 单位为秒;
private:所有内容只有客户端可以缓存,Cache-Control的默认取值。
public:所有内容都将被缓存(客户端和代理服务器都可缓存)。
no-cache:是否使用缓存则需要经过协商缓存来验证决定,需要向服务端发请求询问。
no-store:不使用强制缓存,也不使用协商缓存,必须从服务端获取最新的资源。
四. 协商缓存
当强制缓存未命中,浏览器携带缓存标识向服务器发起请求,由服务器根据缓存标识决定是否使用缓存的过程,主要有以下两种情况
Last-Modified/If-Modified-Since:
浏览器在第一次访问资源时,服务器返回资源的同时,在response header中添加 Last-Modified的header,值是这个资源在服务器上的最后修改时间,浏览器接收后缓存文件和header;
当再次向服务器请求的时候,浏览器就会检测 Last-Modified 这个header 字段,就会添加If-Modified-Since这个header,值就是Last-Modified ,服务器端收到请求 就会把这个字段和文件的最后修改 时间对比,如果不同就会返回 status:200 ,毅力最新的文件,更新缓存时间。
如果没有改变,仅返回 status :304 not Modified 未更新文件及缓存时间,浏览器会直接使用缓存文件。
Etag / If-None-Match
因为 Last-Modified 只能以秒计时,如果在不可感知的时间内修改完成文件,此时 服务端会认为命中了缓存,不会返回正确的资源;
所有http1.1 又增加了 etg 字段, Etag是服务器响应请求时,返回当前资源文件的一个唯一标识(由服务器生成),只要资源有变化,Etag就会重新生成(优先级比Last-Modified高);请求规则和Last-Modified 一致,只是再次请求的字段: If-None-Match
至此 ,浏览器的缓存知识就到这里