讲透浏览器缓存

一、什么是浏览器缓存?

浏览器缓存是一种存储用户访问的网页资源(如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

相关推荐
拉不动的猪13 分钟前
前端常见数组分析
前端·javascript·面试
小吕学编程30 分钟前
ES练习册
java·前端·elasticsearch
Asthenia041237 分钟前
Netty编解码器详解与实战
前端
袁煦丞42 分钟前
每天省2小时!这个网盘神器让我告别云存储混乱(附内网穿透神操作)
前端·程序员·远程工作
一个专注写代码的程序媛2 小时前
vue组件间通信
前端·javascript·vue.js
一笑code2 小时前
美团社招一面
前端·javascript·vue.js
懒懒是个程序员2 小时前
layui时间范围
前端·javascript·layui
NoneCoder2 小时前
HTML响应式网页设计与跨平台适配
前端·html
凯哥19702 小时前
在 Uni-app 做的后台中使用 Howler.js 实现强大的音频播放功能
前端
烛阴2 小时前
面试必考!一招教你区分JavaScript静态函数和普通函数,快收藏!
前端·javascript