前言

今天在刷牛客看面经的时候偶然看见 浏览器缓存 这个词汇,平常开发中很少会去关注这个,也只知道F5会清除缓存,以及开发部署新版本的时候会有缓存导致看不到新版本效果,于是就打算好好了解一下浏览器缓存。

我希望能够尽量清晰明了的讲解,同时考虑到浏览器缓存都是在后台处理,无需用户干预平时也不会过多涉及,所以只会简单介绍一些常见的缓存策略。

缓存策略

  • DNS缓存
  • 本地缓存(memory缓存)
  • Http缓存(强缓存和协商缓存)
  • 服务端缓存(cdn缓存)
  • 浏览器缓存(cookie、localstorage、sessionstorage)

DNS缓存

DNS缓存是浏览器缓存的一种,浏览器会缓存DNS解析结果,减少DNS解析时间,提高网页加载速度。

简单来说就是,我们初次通过域名访问网站时,会将域名解析为IP地址,这个解析结果会被浏览器缓存,下次访问该域名时,浏览器会直接使用缓存中的IP地址,而无需再次进行DNS解析。

本地缓存(memory缓存)

memory cache 是浏览器为了加快读取缓存速度而进行的自身的优化行为,不受开发者控制,也不受 HTTP 协议头的约束。当资源被存入内存后,下次同样的请求将不再通过网络,而是直接访问内存,当关闭该页面时,此资源就被内存释放掉了,再次重新打开相同页面时不再出现from memory cache的情况。

但值得注意的是,memory cache中的资源并不是永久保存的,而是由浏览器自行决定的,当内存不足时,浏览器会自动清理内存中的缓存资源。哪怕页面没有关闭,也有可能被清理掉。

本地缓存实例行为:当页面多次渲染一个图片或者其他资源时,只会请求一次,因为浏览器会将其缓存到本地。

Http缓存(强缓存和协商缓存)

Http缓存是浏览器缓存的一种,浏览器会根据服务器返回的响应头信息,决定是否使用缓存。

强缓存

强缓存不会向服务器发送请求,直接从缓存中读取资源。它通过响应头中的 Expires 和 Cache-Control 控制。Expires 是 HTTP/1.0 的特性,它告诉浏览器在这个时间之前可以直接从缓存中获取资源。而 Cache-Control 是 HTTP/1.1 的特性,它提供了更多的控制选项,如 max-age 指定资源可以缓存多久,no-cache 和 no-store 分别表示资源每次都需要验证或完全不缓存。

总之就是在缓存时间内,浏览器会直接使用缓存中的资源,而不会向服务器发送请求。

协商缓存

协商缓存会向服务器发送请求,由服务器决定是否使用缓存的资源。它通过 Last-Modified 和 ETag 响应头实现。Last-Modified 告诉浏览器资源的最后修改时间,如果请求头中的 If-Modified-Since 日期早于 Last-Modified 日期,则使用缓存。ETag 是资源的唯一标识符,如果请求头中的 If-None-Match 与 ETag 相匹配,则使用缓存。

总之就是在缓存时间内,浏览器会向服务器发送请求,由服务器决定是否使用缓存的资源。

服务端缓存(cdn缓存)

cdn缓存是浏览器缓存的一种,cdn会将资源缓存到全球各地的节点上,当用户访问网站时,cdn会根据用户所在的位置,选择最近的节点,将资源返回给用户,从而加快网页加载速度。

比方说你有两个服务器,一个在北京,一个在广州,当用户在北京访问你的网站时,cdn会将资源从北京的服务器返回给用户,而不会从广州的服务器返回,从而加快网页加载速度。

浏览器缓存(cookie、localstorage、sessionstorage)

cookie、localstorage、sessionstorage是浏览器提供的本地存储方式,它们可以存储一些数据,如用户信息、登录状态等,方便浏览器在下次访问时使用。

不过这些存储方式都有各自的限制,如 cookie 的大小限制为 4KB,localstorage 和 sessionstorage 的大小限制为 5MB。

参考

https://juejin.cn/post/6888875643266662414
https://segmentfault.com/a/1190000044691982