zchfeng / Front-End-note

1 stars 0 forks source link

浏览器缓存 #7

Open zchfeng opened 2 years ago

zchfeng commented 2 years ago

浏览器的缓存过程如下

DNS缓存

通常我们输入一个网址,它包含了域名端口可以指定唯一的IP地址,然后建立连接进行通信,而域名查找IP地址的过程就是dns解析。

www.dnscache.com (域名) - DNS解析 -> 11.222.33.444 (IP地址)

这个过程会对网络请求带来一定的损耗,所以浏览器在第一次获取到IP地址后,会将其缓存起来。下次相同域名再次发起请求时,浏览器会先查找本地缓存,如果缓存有效,则会直接返回该IP地址,否则会继续开始寻址之旅。

memory cache(本地缓存)

memory cache 是浏览器为了加快读取缓存速度而进行的自身的优化行为,不受开发者控制,也不受 HTTP 协议头的约束。当资源被存入内存后,下次同样的请求将不再通过网络,而是直接访问内存,当关闭该页面时,此资源就被内存释放掉了,再次重新打开相同页面时不再出现from memory cache的情况。 那有人会问了,那什么时候资源会被放入memory缓存呢 答案是几乎所有的网络请求资源都会根据相关的策略被浏览器自动加入到 memory cache 中。但是也正因为数量很大但是浏览器占用的内存不能无限扩大这样两个因素,memory cache 注定只能是个“短期存储”。当数据量过大,即使网页不关闭,缓存依然会失效。 memory cache 机制保证了一个页面中如果有两个相同的请求 (例如两个 src 相同的 ,两个 href 相同的 )都实际只会被请求最多一次,避免浪费。

disk cache(HTTP缓存)

硬盘缓存又叫HTTP缓存,它也是浏览器缓存中最重要的内容。因为你想啊,DNS缓存它主要是做一个ip地址查找并且是自主完成的,memory cache 也是不受控制,算是一个黑盒。所以剩下的可以受我们控制的硬盘缓存的重要性就不言而喻了,大多优化手段也是针对硬盘缓存。 HTTP缓存分为强制缓存和协商缓存

强制缓存(强缓存)

对于强缓存,控制它的字段分别是ExpiresCache-Control,其中Cache-Control优先级比Expires高 当客户端发一个请求到服务器,服务器希望你吧资源缓存起来,于生响应头中加入这些内容

Cache-Control: max-age=3600 我希望你把这个资源缓存起来,缓存时间是3600秒(1小时)
Expires: Thu, 10 Nov 2020 08:45:11 GMT 到达指定时间过期
Date: Thu, 30 Apr 2020 12:39:56 GMT
Etag:W/"121-171ca289ebf",(后面协商缓存内容)这个资源的编号是W/"121-171ca289ebf"
Last-Modified:Thu, 30 Apr 2020 08:16:31 GMT,(后面协商缓存内容)这个资源的上一次修改时间

Cache-Control和Expires分别是HTTP/1.1和HTTP/1.0的内容,为了兼容HTTP/1.1和HTTP/1.0,时间项目中两个字段我们都会设置。

浏览器收到这个响应之后就会做下面的事情

这次的记录非常重要,它为以后浏览器要不要去请求服务器提供了记录

之后当客户端准备再次请求同样的地址时,它突然想起了一件事:我需要的东西在不在缓存里呢? 此时,客户端会到缓存中去寻找是否存在缓存的资源,如下

强缓存

协商缓存

一旦发现缓存无效,它并不会简单的把缓存删除,而是抱着一丝希望,想问问服务器,我这个缓存还能继续使用吗?

于是,浏览器香服务器发出了一个带缓存的请求 所谓带缓存的请求,无非就是加入以下的请求头

If-Modified-Since: Thu, 30 Apr 2020 08:16:31 GMT  亲,你曾经告诉我,这个资源的上一次修改时间是格林威治时间2020-04-30 08:16:31,请问这个资源在这个时间之后有发生变动吗?
If-None-Match: W/"121-171ca289ebf"  亲,你曾经告诉我,这个资源的编号是W/"121-171ca289ebf,请问这个资源的编号发生变动了吗?

之所以要发两个信息,是为了兼容不同的服务器,因为有些服务器只认If-Modified-Since,有些服务器只认If-None-Match,有些服务器两个都认,但是一般来说If-None-Match的优先级高于If-Modified-Since 此时可能产生两个结果

协商缓存

Cache-Control

在上述的讲解中,Cache-Control是服务器向客户端响应的一个消息头,它提供了一个max-age用于指定缓存时间。 实际上,Cache-Control还可以设置下面一个或多个值:

比如,Cache-Control: public, max-age=3600表示这是一个公开资源,请缓存1个小时。 不仅仅是在响应头中出现,在http1.1版本中,也可以在请求头中加入Cache-Control: no-cache,它的含义是向服务器表达:不要考虑任何缓存,给我一个正常的结果。这和http1.0版本的消息头字段pragma是一样的功能。

expire

在http1.0版本中,是通过Expire响应头来指定过期时间点的,例如

Expire: Thu, 30 Apr 2020 23:38:38 GMT

到了http1.1版本,已更改为通过Cache-Control的max-age来记录了。

总结

当浏览器再次访问一个已经访问过的资源时,它会这样做: 1.根据相关字段判断是否命中强缓存,如果命中,就直接使用缓存了。 2.如果没有命中强缓存,就发请求到服务器检查是否命中协商缓存。 3.如果命中协商缓存,服务器会返回 304 告诉浏览器使用本地缓存。 4.否则,返回最新的资源。

浏览器缓存缓存策略