讲透浏览器缓存

一、什么是浏览器缓存?

浏览器缓存是一种存储用户访问的网页资源(如HTML页面、图片、JavaScript文件和样式表等)在本地计算机上。

当用户再次访问同一网页时,浏览器可以从本地缓存中读取资源,而不是每次都从服务器重新下载

二、浏览器缓存的优点

减少网络延迟和带宽消耗

减少了服务器的负担,加快网页的加载速度

提高用户的浏览体验

三、缓存在哪儿?

memory cache

不访问服务器,直接读缓存,从内存中读取缓存。

此时的数据是缓存到内存中的,当 kill 进程后,也就是浏览器关闭以后,数据将不存在。但是这种方式只能缓存派生资源

disk cache

不请求网络资源(服务器),直接从磁盘中读取缓存,当 kill 进程时,数据还是存在。

memory 和 disk 的异同?

都属于强缓存,但区别在于,一个是放在内存中(memory)一个是放在磁盘上(disk),所以 memory cache 要比 disk cache 快得多。

但 memory 在浏览器被关闭时会被释放掉,所以当页面再次打开时,就会使用 disk 的缓存。所以就出现了三级缓存的概念。

思考:浏览器如何决定将资源存储在内存还是磁盘中呢?

浏览器会根据资源的类型和大小、浏览器当前状态、缓存策略、浏览器实现和配置以及页面生命周期等因素,智能地决定资源是存储在内存中还是磁盘中,以优化性能和用户体验。

三级缓存原理

  • 先去内存(memory)看,如果有,直接加载
  • 如果内存没有,则取硬盘(disk)获取,如果有直接加载
  • 如果硬盘也没有,那么就进行网络(200)请求
  • 加载到的资源缓存到硬盘和内存

四、浏览器缓存分类?

浏览器在向服务器请求资源时,首先判断是否命中强缓存,再判断是否命中协商缓存!

1. 强缓存(Strong Cache)

浏览器根据响应头中的ExpiresCache-Control字段判断资源是否过期。如果没有过期,命中强缓存,浏览器直接从缓存中读取资源,不会向服务器发送请求。

  • Expires:HTTP/1.0的产物,表示资源过期的绝对时间,例如 Expires: Thu, 01 Dec 1994 16:00:00 GMT。它是基于服务器时间的,如果客户端和服务器时间不同步,可能会导致缓存失效。
  • Cache-Control:HTTP/1.1引入,不受本地系统时间的影响,比 Expires 更加灵活,可以设置多种指令来控制缓存,如 max-age 指定资源可以缓存的最大时间。no-cacheno-store等。例如:Cache-Control: max-age=3600(单位:秒)。
    • no-cache:需要进行协商缓存,发送请求到服务器确认是否使用缓存。这个常和 max-age 共同使用。
    • no-store:禁止使用缓存,每一次都要重新请求数据。
    • public:可以被所有的用户缓存,包括终端用户和 CDN 等中间代理服务器。
    • private:只能被终端用户的浏览器缓存,不允许 CDN 等中继缓存服务器对其缓存。

思考:Cache-Control 与 Expires 可以在服务端配置同时启用,哪个优先级更高?

Cache-Control中的 max-age 提供了相对时间控制,更为精确,优先级更高,浏览器将忽略Expires头,采用max-age来决定缓存策略。

2. 协商缓存(Negotiation Cache)

当强缓存未命中(资源过期)时,浏览器会向服务器发送请求以验证资源是否更新 。通过Last-Modified/If-Modified-SinceETag/If-None-Match头部进行资源验证,判断资源是否被修改。

如果服务器返回 304 状态码,表示资源未修改,浏览器继续从缓存中读取资源;如果资源被修改,服务器会返回新的资源和 200 状态码。

注意:虽然 Last-Modified 提供了一个好的机制来帮助浏览器确定资源是否已被修改,但它可能不总是能完美地反映内容变化的细微差别,特别是在内容短时间内发生变化然后又恢复的情况下。ETag可能提供更精确的缓存验证机制,因为它能够基于内容本身的唯一标识(如哈希值)来判断资源是否真的发生了变化。

  • Last-ModifiedIf-Modified-Since:服务器响应请求时通过 Last-Modified 头告知资源最后修改时间。当浏览器再次请求该资源时,会发送 If-Modified-Since 头,其值为之前收到的 Last-Modified。服务器收到 If-Modify-Since 后,根据资源的最后修改时间判断是否命中缓存。 如果服务器上的资源未被修改命中缓存,则返回 304,浏览器从缓存中加载资源。(简言之:上传新资源后 last-Modify 就会改变,请求的时候带的 if-Modify-Since 是上一次的 last-Modify,两者相对比就能判断出需不需要更新资源)
  • ETagIf-None-Match:返回的是一个验证码,ETag 是资源的唯一标识符。资源变化都会导致ETag变化。服务器根据浏览器上发送的 If-None-Match 值来判断是否命中缓存。如果ETag未改变,服务器返回304状态码,资源从缓存加载。

思考:Last-Modified 与 ETag 是可以一起使用的,是否也存在优先级呢?

ETag提供了比Last-Modified更细粒度的控制,因为它能够检测到资源内容的任何微小变化。因此,尽管HTTP协议没有明确规定两者之间的优先级,但存在ETag时,服务器和浏览器往往会优先考虑使用ETag进行缓存验证,验证 ETag一致的情况下,才会继续比对 Last-Modified,最后才决定是否返回 304。

总结

当浏览器再次访问一个已经访问过的资源时,它会这样做:

  1. 看看是否命中强缓存,如果命中,就直接使用缓存。
  2. 如果没有命中强缓存,就发请求到服务器检查是否命中协商缓存。
  3. 如果命中协商缓存,服务器返回 304 告诉浏览器使用本地缓存。
  4. 否则,返回最新的资源。

缓存策略

为了有效地利用缓存,开发者需要根据资源的更新频率和重要性来设置合适的缓存策略。通常,不变的资源(如库文件)可以设置较长的缓存时间,而频繁更新的资源(如用户个人信息)应该禁止或设置短暂的缓存。

用户控制

用户也可以手动清除浏览器缓存,或通过设置浏览器来禁用缓存。

注意事项

  • 虽然缓存可以提高性能,但不合理的缓存策略也可能导致用户看到过时的内容。
  • 服务端设置缓存策略时需要谨慎,以确保更新能够及时反映到用户端。
  • 浏览器和服务器可能有自己的缓存规则,开发者应该理解并正确配置这些规则。

参考文章:

图解Http缓存控制之max-age=0、no-cache、no-store区别

浏览器缓存(一):强缓存 MEMORY CACHE 和 DISK CACHE

相关推荐
曈欣23 分钟前
vue 中属性值上变量和字符串怎么拼接
前端·javascript·vue.js
QGC二次开发1 小时前
Vue3:v-model实现组件通信
前端·javascript·vue.js·前端框架·vue·html
努力的小雨2 小时前
从设计到代码:探索高效的前端开发工具与实践
前端
小鼠米奇2 小时前
详解Ajax与axios的区别
前端·javascript·ajax
Bunury3 小时前
Vue3新组件transition(动画过渡)
前端·javascript·vue.js
zero.cyx3 小时前
JS函数部分
开发语言·前端·javascript
超级小的大杯柠檬水3 小时前
SpringBoot lombok(注解@Getter @Setter)
java·前端·spring
AvatarGiser3 小时前
《ElementUI/Plus 踩坑》el-table + sortablejs 拖拽顺序错乱(Vue2/3适用)
前端·vue.js·elementui
蓝染-惣右介3 小时前
【若依RuoYi-Vue | 项目实战】帝可得后台管理系统(二)
java·前端·后端·vue·springboot
哈哈哈哈cwl3 小时前
秒懂Vue.jsDiff算法与虚拟DOM
前端·javascript·vue.js