0%

Page Lifecycle API

生命周期流程图

States

Active 活动

在 Active 阶段,网页处于可见状态,且拥有输入焦点。

Passive 被动,消极

在 Passive 阶段,网页可见,但没有输入焦点,无法接受输入。UI 更新(比如动画)仍然在执行。该阶段只可能发生在桌面同时有多个窗口的情况。

Hidden 隐藏

在 Hidden 阶段,用户的桌面被其他窗口占据,网页不可见,但尚未冻结。UI 更新不再执行。

Frozen 冻结

如果网页处于 Hidden 阶段的时间过久,用户又不关闭网页,浏览器就有可能冻结网页,使其进入 Frozen 阶段。不过,也有可能,处于可见状态的页面长时间没有操作,也会进入 Frozen 阶段。

这个阶段的特征是,网页不会再被分配 CPU 计算资源。定时器、回调函数、网络请求、DOM 操作都不会执行,不过正在运行的任务会执行完。浏览器可能会允许 Frozen 阶段的页面,周期性复苏一小段时间,短暂变回 Hidden 状态,允许一小部分任务执行。

Terminated 终止

在 Terminated 阶段,由于用户主动关闭窗口,或者在同一个窗口前往其他页面,导致当前页面开始被浏览器卸载并从内存中清除。注意,这个阶段总是在 Hidden 阶段之后发生,也就是说,用户主动离开当前页面,总是先进入 Hidden 阶段,再进入 Terminated 阶段。

这个阶段会导致网页卸载,任何新任务都不会在这个阶段启动,并且如果运行时间太长,正在进行的任务可能会被终止。

Discarded 丢弃

如果网页长时间处于 Frozen 阶段,用户又不唤醒页面,那么就会进入 Discarded 阶段,即浏览器自动卸载网页,清除该网页的内存占用。不过,Passive 阶段的网页如果长时间没有互动,也可能直接进入 Discarded 阶段。

这一般是在用户没有介入的情况下,由系统强制执行。任何类型的新任务或 JavaScript 代码,都不能在此阶段执行,因为这时通常处在资源限制的状况下。

网页被浏览器自动 Discarded 以后,它的 Tab 窗口还是在的。如果用户重新访问这个 Tab 页,浏览器将会重新向服务器发出请求,再一次重新加载网页,回到 Active 阶段。

获取当前阶段

1
2
3
4
5
6
7
8
9
const getState = () => {
if (document.visibilityState === "hidden") {
return "hidden";
}
if (document.hasFocus()) {
return "active";
}
return "passive";
};

另一方面,frozen 和 terminated 状态只能在状态发生变化时在其各自的事件侦听器(freeze and pagehide)中检测到。

如何防止在页面隐藏时被 Frozen 或 Discarded

  • 播放音频
  • 使用 WebRTC
  • 使用 WebSockets
  • 更新 title 或 favicon
  • 显示 alert
  • 发送 push 消息

具体参考: Heuristics for Freezing & Discarding

测试工具

chrome://discards

参考连接

https://www.ruanyifeng.com/blog/2018/11/page_lifecycle_api.html
https://developer.chrome.com/blog/page-lifecycle-api/