一般来说,缓存可以通过存储数据来提升性能,以便更快地处理对同一数据的后续请求。例如,网络中的缓存资源可以避免往返服务器。缓存的计算结果可以省去进行相同计算的时间。
在 Chrome 中,缓存机制的使用方式多种多样,HTTP 缓存就是其中之一。
Chrome 的 HTTP 缓存目前的工作原理
从版本 85 开始,Chrome 会缓存从网络提取的资源,并使用相应的资源网址作为缓存键。(缓存键用于标识缓存的资源。)
以下示例展示了在三种不同情境中如何缓存和处理单张图片:

https://x.example/doge.png
}
用户访问请求图片 (https://x.example/doge.png
) 的网页 (https://a.example
)。系统会从网络请求图片,并使用 https://x.example/doge.png
作为键进行缓存。

https://x.example/doge.png
}
同一用户访问另一个网页 (https://b.example
),该网页请求相同的图片 (https://x.example/doge.png
)。浏览器会检查其 HTTP 缓存,以图片网址为键,确定是否已缓存此资源。浏览器在其缓存中找到匹配项,因此会使用资源的缓存版本。

https://x.example/doge.png
}
图片是从 iframe 中加载的,这无关紧要。如果用户访问包含 iframe (https://d.example
) 的其他网站 (https://c.example
),并且 iframe 请求相同的图片 (https://x.example/doge.png
),浏览器仍可以从其缓存中加载该图片,因为所有网页的缓存键都是相同的。
从效果角度来看,这种机制长期以来一直运行良好。不过,网站响应 HTTP 请求所需的时间可能会泄露浏览器过去访问过相同资源的信息,从而使浏览器受到安全和隐私攻击,例如:
- 检测用户是否访问过特定网站:攻击者可以通过检查缓存中是否包含可能特定于特定网站或网站同类群组的资源,来检测用户的浏览记录。
- 跨网站搜索攻击:攻击者可以通过检查特定网站使用的“无搜索结果”图片是否在浏览器的缓存中,来检测用户的搜索结果中是否包含任意字符串。
- 跨网站跟踪:缓存可用作跨网站跟踪机制来存储类似 Cookie 的标识符。
为降低这些风险,从 Chrome 86 开始,Chrome 将对其 HTTP 缓存进行分区。
缓存分区对 Chrome 的 HTTP 缓存有何影响?
借助缓存分区,系统将使用新的“网络隔离键”以及资源网址对缓存的资源进行键控。网络隔离键由顶级网站和当前框架网站组成。
再来看看前面的示例,了解缓存分区在不同情境中的运作方式:

https://a.example
, https://a.example
, https://x.example/doge.png
}
用户访问一个请求图片 (https://x.example/doge.png
) 的网页 (https://a.example
)。在这种情况下,系统会从网络请求图片,并使用键值对(包括 https://a.example
[顶级网站]、https://a.example
[当前框架网站] 和 https://x.example/doge.png
[资源网址])将图片缓存起来。(请注意,当资源请求来自顶级框架时,网络隔离键中的顶级网站和当前框架网站是相同的。)

https://b.example
, https://b.example
, https://x.example/doge.png
}
同一用户访问另一个请求同一图片 (https://x.example/doge.png
) 的页面 (https://b.example
)。虽然上例中加载了同一图片,但由于键不匹配,因此不会命中缓存。
系统会从网络请求图片,并使用由 https://b.example
、https://b.example
和 https://x.example/doge.png
组成的元组作为键进行缓存。

https://a.example
, https://a.example
, https://x.example/doge.png
}
现在,用户返回到 https://a.example
,但这次图片 (https://x.example/doge.png
) 嵌入在 iframe 中。在本例中,键是一个包含 https://a.example
、https://a.example
和 https://x.example/doge.png
的元组,并且发生了缓存命中。(请注意,当顶级网站和 iframe 是同一网站时,可以使用使用顶级框架缓存的资源。

https://a.example
, https://c.example
, https://x.example/doge.png
}
用户又回到了 https://a.example
,但这次图片托管在 https://c.example
中的 iframe 中。
在本例中,系统会从网络下载图片,因为缓存中没有与由 https://a.example
、https://c.example
和 https://x.example/doge.png
组成的键匹配的资源。

https://a.example
, https://c.example
, https://x.example/doge.png
}
如果域名包含子网域或端口号,该怎么办?用户访问 https://subdomain.a.example
,其中嵌入了 iframe (https://c.example:8080
),该 iframe 会请求图片。
由于密钥是根据“scheme://eTLD+1”创建的,因此系统会忽略子网域和端口号。因此,会发生缓存命中。

https://a.example
, https://c.example
, https://x.example/doge.png
}
如果 iframe 嵌套多次,该怎么办?用户访问 https://a.example
,该网页嵌入了一个 iframe (https://b.example
),该 iframe 又嵌入了另一个 iframe (https://c.example
),后者最终会请求图片。
由于键取自顶级帧 (https://a.example
) 和加载资源的直接帧 (https://c.example
),因此会发生缓存命中。
常见问题解答
我的 Chrome 上是否已启用此功能?该如何确认?
此功能将于 2020 年底前推出。如需检查您的 Chrome 实例是否已支持该功能,请执行以下操作:
- 打开
chrome://net-export/
,然后按 Start Logging to Disk(开始记录至磁盘)。 - 指定日志文件在计算机上的保存位置。
- 在 Chrome 中浏览网页一分钟。
- 返回
chrome://net-export/
,然后按 Stop Logging(停止记录)。 - 前往
https://netlog-viewer.appspot.com/#import
。 - 按 Choose File(选择文件),然后传递您保存的日志文件。
您会看到日志文件的输出。
在同一页面上,找到 SplitCacheByNetworkIsolationKey
。如果后跟 Experiment_[****]
,则表示 Chrome 上启用了 HTTP 缓存分区。如果后跟 Control_[****]
或 Default_[****]
,则表示未启用。
如何在 Chrome 中测试 HTTP 缓存分区?
如需在 Chrome 上测试 HTTP 缓存分区,您需要使用命令行标志 --enable-features=SplitCacheByNetworkIsolationKey
启动 Chrome。请按照使用标志运行 Chromium 中的说明,了解如何在您的平台上使用命令行标志启动 Chrome。
作为 Web 开发者,我需要采取什么措施来应对这项变更?
这不是破坏性更改,但可能会对某些 Web 服务造成性能影响。
例如,在许多网站上提供大量可缓存资源(例如字体和热门脚本)的网站可能会看到流量增加。此外,使用此类服务的用户可能会对其更加依赖。
(有一个提案提出了一种可保护隐私的方式来启用共享库,称为网站共享库(演示视频),但该提案仍在审核中。)
这种行为变化有何影响?
总缓存缺失率增加约 3.6%,FCP(首次有内容绘制)的变化幅度较小(约 0.3%),从网络加载的字节总比例增加约 4%。如需详细了解对性能的影响,请参阅 HTTP 缓存分区说明。
这是否标准化了?其他浏览器的行为是否有所不同?
“HTTP 缓存分区”已在提取规范中标准化,但浏览器的行为有所不同:
- Chrome:使用顶级 scheme://eTLD+1 和框架 scheme://eTLD+1
- Safari:使用顶级 eTLD+1
- Firefox:计划使用 scheme://eTLD+1 实现,并考虑添加第二个键(如 Chrome)
如何处理从 worker 提取数据?
专用工作器使用与其当前帧相同的键。Service Worker 和共享 worker 更复杂,因为它们可能会在多个顶级网站之间共享。我们目前正在讨论解决方案。