废弃卸载事件

我们将逐步更改 unload 事件的默认值,逐步将其弃用,使 unload 处理程序停止在网页上触发,除非网页明确选择启用以重新启用这些事件。

弃用时间表

我们在 2019 年 1 月宣布打算实现往返缓存时,就注意到了卸载行为可能会有所变化。在实施工作的同时,我们还进行了一次大规模的推广活动,使卸载量大幅下降。为了进一步完善此次推广活动,我们还开始提供各种方法,以便测试弃用 Chrome 115 中卸载卸载功能的效果:

在主动联系和试用阶段之后,我们预计将按以下方式进行软弃用

  • 限定了范围的阶段,在此阶段中,排名前 50 的热门网站将逐渐停止卸载(在撰写本文时,参考文档)。
    • 从 1% 的 Chrome 120 用户开始(截至 2023 年 11 月底)。
    • 到 2024 年第 3 季度末覆盖所有用户
  • 此外,从 2024 年第 3 季度开始,我们打算启动一个通用阶段,即从 1% 的用户开始,到 2025 年第 1 季度末,将逐步停止在所有网站上执行卸载操作。

请注意,我们还提供了停用选项菜单,以防此软弃用时间表没有足够的时间完成卸载操作。我们的目标是根据这一软弃用来告知最后一个阶段(强制弃用卸载)的时间表。在这一阶段,这些停用选项将被移除或减少。

废弃卸载的时间表。

背景

unload 设计为在取消加载文档时触发。从理论上讲,它可用于在用户离开页面时运行代码,或用作会话结束回调。

此事件最常使用的场景包括:

  • 保存用户数据:在离开网页之前保存数据。
  • 执行清理任务:在放弃页面前关闭打开的资源。
  • 发送分析数据:在会话结束时发送与用户互动相关的数据。

但是,unload 事件极不可靠

在桌面版 Chrome 和 Firefox 中,unload 相当可靠,但它会阻止使用 bfcache(往返缓存),因此会对网站性能产生负面影响。

在移动浏览器中,unload 通常不会运行,因为标签页经常在后台运行,然后被终止。因此,浏览器会优先在移动设备上执行 bfcache,而非 unload,这使得它们更加不可靠。Safari 在桌面设备上也会采用此行为。

Chrome 团队认为,在移动设备上使用 bfcache 比在桌面设备上优先使用 unload 的模式会造成干扰,因为这种模型在 Chrome 和 Firefox 中也更加不可靠,而以前在 Chrome(和 Firefox)中相当可靠。Chrome 的目标是彻底移除 unload 事件。在此之前,对于已明确选择不进行弃用的用户,此应用仍可在桌面设备上正常运行。

为什么要废弃 unload 事件?

废弃 unload 是更全面地识别我们当前所处网络的关键一步。unload 事件会给人一种对应用生命周期的虚假控制感,人们在现代计算世界中浏览网页的方式已经越来越不真实。

移动操作系统经常会冻结或卸载网页以节省内存,而桌面浏览器现在也会出于同样的原因这样做越来越多。即使没有操作系统干预,用户自己也会频繁切换标签页并终止旧标签页,而无需正式“离开页面”。

移除过时的 unload 事件意味着,我们作为 Web 开发者,需要确保我们的范式与现实世界保持一致,而不是依赖于不再成立的过时概念(如果它们曾经适用)。

unload 事件的替代方案

建议使用以下代码,而不是 unload

  • visibilitychange:用于确定网页的公开范围何时发生变化。当用户切换标签页、最小化浏览器窗口或打开新页面时,就会发生此事件。将 hidden 状态视为保存应用和用户数据的最后可靠时间。
  • pagehide:用于确定用户何时离开了页面。当用户离开页面、重新加载页面或关闭浏览器窗口时,就会发生此事件。只是将网页最小化或切换到其他标签页时,不会触发 pagehide 事件。请注意,由于 pagehide 不会使网页不再符合储存于往返缓存的条件,因此网页在此事件触发后有可能恢复。如果您要清理此事件中的任何资源,可能必须在页面恢复时恢复这些资源。

beforeunload 事件与 unload 的用例略有不同,因为它是可取消事件。它通常用于在用户离开网页时提醒他们有未保存的更改。此事件也无法实现,因为如果后台标签页被终止,该事件也不会触发。建议您限制 beforeunload 的使用,并且仅根据条件添加。对于大多数 unload 替换事件,请使用上述事件。

如需了解详情,请参阅关于从不使用 unload 处理程序的建议

检测 unload 的使用情况

您可以借助不同的工具查找 unload 事件在网页上的呈现效果。这样一来,网站可以了解自己是在使用自己的代码还是通过库使用此事件,因此可能会受到即将弃用的这一事件的影响。

灯塔

Lighthouse 接受 no-unload-listeners 审核,会在其网页上的任何 JavaScript(包括来自第三方库的 JavaScript)添加了 unload 事件监听器时向开发者发出警告。

显示正在使用的卸载处理程序的 Lighthouse 审查

Chrome DevTools

Chrome 开发者工具包含 back-foward-cache 审核,可帮助您发现可能会阻止您的网页储存至往返缓存的问题,包括使用 unload 处理程序。

若要测试往返缓存,请按以下步骤操作:

  1. 在您的页面上,打开开发者工具,然后依次转到应用 > 后台服务 > 往返缓存

  2. 点击测试往返缓存,Chrome 会自动将您带回 chrome://terms/ 并返回您的网页。或者,您也可以点击浏览器的后退和前进按钮。

如果您的网页不符合往返缓存的条件,往返缓存标签页会显示问题列表。在“可操作”下,您可以看到是否使用了 unload

显示使用了卸载处理程序的 Chrome 开发者工具的往返缓存测试工具

报告 API

Reporting API 可与只读权限政策结合使用,以检测网站用户对 unload 的使用情况。

如需了解详情,请参阅使用 Reporting API 查找卸载操作

Bfcache notRestoredReasons API

notRestoredReasons 属性(已添加到 PerformanceNavigationTiming 类)可报告有关文档是否被禁止在导航时使用 bfcache 以及原因的信息。如需查看使用说明,请点击此处。现有 unload 监听器的响应对象警告如下所示:

{
   blocked: true,
   children: [],
   id: "",
   name: "",
   reasons: [ "Internal Error", "Unload handler" ],
   src: "",
   url: "a.com"
}

控制对unload的访问权限

Chrome 会逐步弃用 unload 事件。在此期间,您可以使用不同的工具来控制此行为,并为即将进行的弃用做好准备。请注意,您不应长期依赖这些技术,而应尽快计划迁移到替代方案。

利用以下选项,您可以启用或停用unload处理程序,测试在没有处理程序的情况下您的网站如何运行,从而为即将进行的弃用做好准备。有以下不同类型的政策:

  • 权限政策:这是一种平台 API,可供网站所有者通过使用 HTTP 标头在网站一级或单个网页一级控制对各项功能的访问权限。
  • 企业政策:IT 管理员为组织或企业配置 Chrome 的工具。但可以通过管理控制台(例如 Google 管理控制台)进行配置。
  • Chrome flag:这可让个人开发者更改 unload 弃用设置,以测试对各个网站的影响。

权限政策

Chrome 115 中新增了权限政策,以允许网站选择停用 unload 处理程序,并立即从 bfcache 提升网站性能。请参阅这些示例,了解如何为网站设置此功能。这样,网站就可以在 unload 被弃用之前提前采取行动。

将在 Chrome 117 中得到扩展,以允许网站采取反向操作,并选择继续尝试触发 unload 处理程序,因为 Chrome 会将这些处理程序的默认设置更改为日后不触发。请参阅这些示例,了解如何继续允许您的网站触发卸载处理程序。这项选择启用设置不会永久保留,您应让系统有时间让网站停止使用 unload 处理程序。

企业政策

如果企业的软件依赖于 unload 事件才能正常运行,可以使用 ForcePermissionPolicyUnloadDefaultEnabled 政策来防止受其控制的设备被逐步弃用。启用此政策后,unload 将继续默认为所有源启用。网页仍可能会根据需要设置更严格的政策。与停用权限政策一样,此工具也可以减少潜在的破坏性更改,但不应无限期使用。

Chrome 标志和命令行开关

除了企业政策之外,您还可以通过 Chrome 标志和命令行开关针对个别用户停用弃用功能:

如果将 chrome://flags/#deprecate-unload 设为 enabled,将采用弃用默认设置,并阻止触发 unload 处理程序。您仍然可以通过“权限政策”逐个网站替换它们,但默认情况下仍会继续触发。

这些设置也可以通过命令行开关控制。

选项比较

下表总结了之前讨论的选项的不同用途:

将弃用时间提前 提前弃用(但有例外情况) 防止弃用,确保为迁移留出时间
权限政策
(适用于网页/网站)
企业政策
(适用于设备)
Chrome 标记
(适用于个人用户)
Chrome 命令行开关
(适用于个别用户)

总结

unload 处理程序即将被弃用。它们在很长一段时间内一直不可靠,并且不能保证文档在所有情况下都能触发。此外,unload 处理程序与 bfcache 不兼容。

目前使用 unload 处理程序的网站应该为这一即将到来的弃用做好准备,具体方法是:测试所有现有的 unload 处理程序,移除或迁移这些处理程序;在万不得已的情况下,在需要更多时间时推迟弃用。

致谢

感谢 Kenji Baheux、Fergal Daly、Adriana Jara 和 Jeremy Wagner 帮助审核本文。

主打图片由 Anja BauermannUnsplash 上提供