浏览器的启发式缓存实际上会缓存多久

启发式缓存

启发式缓存是浏览器缓存的默认行为(即对于没有Cache-Control的响应),它并非简单的"不缓存",而是基于所谓的"启发式缓存"进行隐式缓存。HTTP 的设计初衷是尽可能地缓存,所以即使未指定Cache-Control,只要满足一定条件,响应也会被存储并重用。这就是所谓的启发式缓存。

例如,一个 HTTP 响应头可能如下所示:

yaml 复制代码
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 1024
Date: Tue, 22 Feb 2022 22:22:22 GMT
Last-Modified: Tue, 22 Feb 2021 22:22:22 GMT

缓存时长

缓存时长的计算公式可以简化为:(Date - Last-Modified) * 0.1。 其中,Date是当前请求的时间,Last-Modified是服务器上资源最后修改的日期。

根据 MDN 的说法,一整年都未更新的内容在之后的一段时间内也不太可能更新。因此,客户端会存储这个响应(即使没有max-age)并在一段时间内重用它。重用响应的时长取决于具体实现,但规范建议存储大约自上次更新后时间的 10%(在此例中为 0.1 年)。

这意味着,如果一个资源有 10 天没有更新,它将被缓存 1 天。在这段时间内,浏览器请求将使用本地缓存,超过这段时间后,浏览器将向服务器请求资源。

启发式缓存是在Cache-Control被广泛采用之前出现的一种解决方案,现在基本上所有的响应都应该显式指定Cache-Control头。

原理解析

这可能有点令人困惑,让我们详细解释一下。默认的缓存时间是多久,又是如何确定的呢?

如果一个文件没有指定缓存策略,浏览器将默认使用启发式缓存。

接下来,我们需要查看文件响应头中的DateLast-Modified信息。这两个时间是决定浏览器在下次页面刷新后是向服务器请求还是使用本地缓存的关键因素。请注意,这是针对下一次请求而言。

当前请求的响应头中(Date - Last-Modified) * 0.1决定了文件将被缓存的时长。例如,如果DateLast-Modified之间的差值为(2023 - 04 - 13 - 2023 - 03 - 09)35 天(忽略具体时间),那么文件将被缓存大约 3.5 天。如果用户在接下来的 3.5 天内请求这个文件,浏览器将从本地缓存中获取它。如果文件被缓存已经超过 3.5 天,浏览器将向服务器请求资源而不是使用缓存。

只要Last-Modified(文件的最后修改时间)保持不变,随着时间的推移,资源的缓存时间会变长。

DateLast-Modified差值较短的情况下,开发人员在测试启发式缓存时可能会感到困惑。他们可能无法看到启发式缓存的效果。要正确分析和判断启发式缓存,只需按照上述计算方法逐步进行分析即可。

让我们再次以同一个文件为例。假设服务器修改了文件的内容,DateLast-Modified之间的差值只有 27 秒。这意味着文件将只被缓存 2.7 秒。由于我们刚刚在服务器上修改了内容,我们需要强制刷新才能获取最新文件,这意味着请求将发送到服务器而不是使用本地缓存。因此,使用强制刷新我们无法看到启发式缓存的效果。要看到效果,我们需要再次修改服务器上的文件内容,然后使用普通刷新来查看文件是否使用了启发式缓存。

在修改服务器资源并刷新页面后,我们可以看到config.js仍然在请求服务器资源。这意味着它没有使用缓存。如果它使用了缓存,Size列将显示disk cachememory cache。这是因为前一次请求的DateLast-Modified决定了下一次请求是否使用缓存。在这种情况下,前一次请求只缓存了文件 2.7 秒,并且由于我们在修改服务器资源后超过 2.7 秒才刷新页面,浏览器不得不再次从服务器请求文件。

因此,在测试启发式缓存时,重要的是尝试增加DateLast-Modified之间的差值以查看效果。

例如,如果我们将差值增加到 16 分钟,文件将被缓存大约 90 秒(49 - 33)* 0.1。

在这段时间内,如果我们修改服务器上的资源并刷新页面,我们将看到config.js使用的是缓存版本而不是请求服务器资源。然而,我们应该注意,在这段缓存时间内,我们将无法看到服务器上的最新内容,因此对于系统配置文件配置协商缓存非常重要。

相关推荐
Hilaku22 分钟前
我用 Gemini 3 Pro 手搓了一个并发邮件群发神器(附源码)
前端·javascript·github
IT_陈寒23 分钟前
Java性能调优实战:5个被低估却提升30%效率的JVM参数
前端·人工智能·后端
快手技术24 分钟前
AAAI 2026|全面发力!快手斩获 3 篇 Oral,12 篇论文入选!
前端·后端·算法
颜酱25 分钟前
前端算法必备:滑动窗口从入门到很熟练(最长/最短/计数三大类型)
前端·后端·算法
全栈前端老曹34 分钟前
【包管理】npm init 项目名后底层发生了什么的完整逻辑
前端·javascript·npm·node.js·json·包管理·底层原理
HHHHHY40 分钟前
mathjs简单实现一个数学计算公式及校验组件
前端·javascript·vue.js
boooooooom43 分钟前
Vue3 provide/inject 跨层级通信:最佳实践与避坑指南
前端·vue.js
一颗烂土豆43 分钟前
Vue 3 + Three.js 打造轻量级 3D 图表库 —— chart3
前端·vue.js·数据可视化
青莲84344 分钟前
Android 动画机制完整详解
android·前端·面试
iReachers1 小时前
HTML打包APK(安卓APP)中下载功能常见问题和详细介绍
前端·javascript·html·html打包apk·网页打包app·下载功能