往返缓存 (BFCache) 是一种浏览器优化功能,可实现即时返回和前进导航。我们将更改 Chrome BFCache,这可能会影响使用消息端口的扩展程序。如果您拥有的 Chrome 扩展程序使用消息传递在内容脚本和扩展程序之间进行通信,请继续阅读,了解如何测试和调整扩展程序。
扩展消息端口
扩展程序通过消息传递与内容脚本或其他扩展程序进行通信。您可以通过调用 runtime.sendMessage()
和 tabs.sendMessage()
或使用可重复使用的消息端口,使用一次性请求发送消息。只要该端口处于活动状态,内容脚本和扩展程序后台脚本都可以重复使用该端口来相互发送消息。
如需了解详情,请参阅消息传递。
往返缓存
当用户离开符合 BFCache 条件的网页时,浏览器会允许该网页及其所有状态保留在内存中,但处于非完全活跃状态。如果用户执行历史记录导航(返回或前进)到缓存的网页,浏览器会尝试从 BFCache 恢复该网页。这有助于加快导航速度并改善用户的浏览体验。
当网页位于 BFCache 中时,它处于冻结状态,不允许执行 JavaScript。这意味着它无法处理收到的消息。
如需了解详情,请参阅往返缓存。
扩展程序消息端口对 BFCache 的影响
简而言之,扩展程序向 BFCache 中的网页发送消息可能会导致缓存被驱逐并影响性能。
当包含打开的扩展程序消息端口的网页存储在 BFCache 中时,该端口会保持打开状态。从 BFCache 恢复网页后,扩展程序服务工作器仍可使用消息端口的旧引用将消息发布到内容脚本。
不过,如果扩展程序在网页仍位于 BFCache 中时尝试通过该消息端口发布消息,则消息会发送,但由于处理程序已冻结,因此无法完全传送。由于消息加入队列和丢弃消息都有各自的问题,因此扩展程序很难推理和解决这种情况。
为避免出现与消息丢失相关的问题,在 Chrome 的当前实现中,它会从 BFCache 中驱逐主页并舍弃消息。如果用户返回该页面,系统会重新加载该页面,以便扩展程序设置新的连接。
另一方面,此实现会限制 BFCache 适用的场景,从而限制性能提升,尤其是对于具有广播或心跳机制且会定期向所有连接发送消息的扩展程序。此外,由于在扩展程序向内容脚本发送消息时会触发驱逐,因此 Web 开发者无法阻止其网页被驱逐。
为了提高整体性能,我们计划引入新的消息端口行为。
新行为:在页面存储在 BFCache 中时关闭消息通道
从 Chrome 123 开始,当包含打开的扩展程序消息端口的网页存储在 BFCache 中时,系统会从内容脚本端主动关闭底层消息通道。因此,所有消息端口都会关闭,并且扩展程序将收到 onDisconnect
事件。
由于该通道已关闭,因此在页面位于 BFCache 中时,系统不会向该页面发送任何消息。因此,该网页不会因延长期限而被驱逐。
即使从 BFCache 恢复页面,已关闭的消息渠道也不会重新打开。建议扩展程序作者监听网页生命周期事件,并在从 BFCache 恢复网页时设置新连接,如以下示例所示。
// content script
let port;
window.addEventListener('pageshow', (event) => {
if (event.persisted) {
// The page is restored from BFCache, set up a new connection.
port = chrome.runtime.connect();
}
});
详细了解不同浏览器代表之间的 WECG 对话(在问题 474 下)。
我会受到影响吗?
新行为将在 Chrome 123 中通过标志提供,以便您测试代码。如需了解详情,请参阅时间表。请按照以下步骤测试您的扩展程序。请注意,此功能仅提供简单的测试,我们建议您启用此功能并运行 Chrome 一段时间,因为很难预测扩展程序中的哪些功能可能会导致问题。
测试新行为
如需在 Chrome 123 中强制启用实验,请执行以下操作:
使用以下标志启动 Chrome,以强制执行新行为:
--enable-features=DisconnectExtensionMessagePortWhenPageEntersBFCache
前往某个网页,并根据需要与您的扩展程序互动,以便内容脚本打开指向您的扩展程序的端口。
退出并返回。页面现在应该已恢复,但内容脚本和服务工件之间的消息通道应已断开连接。
测试扩展程序是否仍能正常运行,如果不能,您应按照上一部分所示手动重新连接。
使用旧行为找出简单问题
在此更改之前,如果您尝试向与 bfcache 中的某个网页关联的端口发送消息,Chrome 会显示一条警告。这对于发现涉及从后台发送到页面的消息的一些问题(但不是全部问题)很有帮助。
- 确保 Chrome 版本至少为 123。最好使用 Chrome Canary,因为它提供了额外的警告,有助于简化测试。
使用以下标志启动 Chrome,以强制使用旧行为:
--disable-features=DisconnectExtensionMessagePortWhenPageEntersBFCache
在未运行扩展程序的情况下,前往符合 BFCache 条件的网页(例如 https://example.com/ 等简单网站)。请按照 BFCache 教程操作,确保从 BFCache 恢复该数据。
安装并启用该扩展程序,然后再次测试 BFCache 的资格条件。您可以手动离开该页面,等待足够长的时间(以便您的扩展程序向 BFCached 页面发布消息),然后返回该页面。
如果由于逐出而必须从新加载网页(而不是从 BFCache 加载),并且导致无法恢复的问题是“ExtensionSentMessageToCachedFrame”,则该扩展程序可能会受到此更改的影响。
在 Chrome Canary 124.0.6315.0 及更高版本中,您还会在该页面中看到以下警告:
当网页未从 BFCache 恢复时显示的警告。
确认扩展程序正在向 BFCache 页面发布消息后,您可以按照上一部分中的步骤强制启用实验,并观察是否有任何逻辑出现故障。
发布时间表
我们计划从 Chrome 123 开始逐步扩大新行为的覆盖范围。以下是详细计划:
日期 | 计划的里程碑 |
---|---|
2 月 15 日 | 在 Chrome 123 Canary 和开发者版中启动针对新行为的实验。 |
3 月 7 日 | 在 Chrome 123 Beta 版中开始针对新行为的实验。 |
3 月 18 日 | 面向 4% 的 Chrome 123 稳定版用户发布新行为。 |
3 月 25 日 | 面向 Chrome 123 稳定版的 50% 用户发布新行为。 |
4 月 2 日 | 实验结束,新行为将成为默认行为。 |