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

启发式缓存

启发式缓存是浏览器缓存的默认行为(即对于没有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使用的是缓存版本而不是请求服务器资源。然而,我们应该注意,在这段缓存时间内,我们将无法看到服务器上的最新内容,因此对于系统配置文件配置协商缓存非常重要。

相关推荐
辻戋3 分钟前
从零实现React Scheduler调度器
前端·react.js·前端框架
徐同保5 分钟前
使用yarn@4.6.0装包,项目是react+vite搭建的,项目无法启动,报错:
前端·react.js·前端框架
Qrun1 小时前
Windows11安装nvm管理node多版本
前端·vscode·react.js·ajax·npm·html5
中国lanwp1 小时前
全局 npm config 与多环境配置
前端·npm·node.js
JELEE.2 小时前
Django登录注册完整代码(图片、邮箱验证、加密)
前端·javascript·后端·python·django·bootstrap·jquery
TeleostNaCl4 小时前
解决 Chrome 无法访问网页但无痕模式下可以访问该网页 的问题
前端·网络·chrome·windows·经验分享
前端大卫5 小时前
为什么 React 中的 key 不能用索引?
前端
你的人类朋友6 小时前
【Node】手动归还主线程控制权:解决 Node.js 阻塞的一个思路
前端·后端·node.js
小李小李不讲道理7 小时前
「Ant Design 组件库探索」五:Tabs组件
前端·react.js·ant design
毕设十刻7 小时前
基于Vue的学分预警系统98k51(程序 + 源码 + 数据库 + 调试部署 + 开发环境配置),配套论文文档字数达万字以上,文末可获取,系统界面展示置于文末
前端·数据库·vue.js