页面可见性 API
页面可见性 API 提供了一些事件,你可以通过查看这些事件来了解文档何时变为可见或隐藏,还提供了一些功能来查看页面的当前可见性状态。
通过让页面在文档不可见时避免执行不必要的任务,这对于节省资源和提高性能特别有用。
概念与用途
当用户最小化窗口或切换到另一个标签页时,API 会发送 visibilitychange
事件,让监听者知道页面的状态已发生变化。你可以检测到该事件并执行某些操作或采取不同的行为。例如,如果你的 web 应用正在播放视频,当用户将标签页放到后台时,它可以暂停视频,当用户返回标签页时,它又可以恢复播放。用户不会失去在视频中的位置,视频的配乐也不会干扰新的前台标签页中的音频,用户在此期间也不会错过任何视频。
<iframe>
的可见性状态与父文档相同。使用 CSS 属性(如 display: none;
)隐藏 <iframe>
不会触发可见性事件,也不会改变框架内文档的状态。
使用情景
制定有助于后台页面性能的策略
在页面可见性 API 之外,用户代理会采取许多策略来减轻后台或隐藏选项卡对性能的影响。这些可能包括:
-
大多数浏览器会停止向后台标签页或隐藏的
<iframe>
发送requestAnimationFrame()
回调,以提高性能和电池寿命。 -
在后台或不活动标签页中,
setTimeout()
等计时器会被限流,以帮助提高性能。详情请参阅延迟时间超过指定时间的原因。 -
浏览器实施基于预算的后台超时限流。现代浏览器的操作方式大同小异,具体细节如下:
- 在 Firefox 中,后台标签页中的每个窗口都有自己的时间预算(以毫秒为单位),最大值和最小值分别为 +50 毫秒和 -150 毫秒。Chrome 浏览器与之非常相似,只是预算以秒为单位。
- 窗口在 30 秒后会受到限流,限流延迟规则与为窗口定时器指定的规则相同(请再次参阅延迟时间超过指定时间的原因)。在 Chrome 浏览器中,该值为 10 秒。
- 只有当预算为非负数时,才允许执行定时器任务。
- 定时器代码一旦运行完毕,其执行时间就会从窗口的超时预算中扣除。
- 在 Firefox 和 Chrome 浏览器中,预算以每秒 10 毫秒的速度重新生成。
某些进程不受这种限流行为的影响。在这种情况下,可以使用页面可见性 API 来减少标签页隐藏时对性能的影响。
对其他接口的扩展
实例属性
页面可见性 API 为 Document
接口添加了以下属性:
-
如果页面处于隐藏状态,则返回
true
,否则返回false
。 Document.visibilityState
只读-
说明文档当前可见性状态的字符串。可能的值有:
visible
-
页面内容至少部分可见。在实践中,这意味着页面是非最小化窗口的前景选项卡。
-
页面内容对用户不可见,原因可能是文档标签页在后台或属于最小化窗口的一部分,也可能是设备屏幕关闭。
事件
页面可见性 API 为 Document
接口添加了以下事件:
visibilitychange
-
当标签页的内容变为可见或被隐藏时触发。
示例
在页面隐藏时暂停音频
该示例会在用户切换到不同标签页时暂停音频,并在用户切换回标签页时播放音频。
HTML
<audio
controls
src="https://mdn.github.io/webaudio-examples/audio-basics/outfoxing.mp3"></audio>
JavaScript
const audio = document.querySelector("audio");
// 处理页面可见性变化:
// - 如果页面隐藏,暂停音频
// - 如果页面显示,播放音频
document.addEventListener("visibilitychange", () => {
if (document.hidden) {
audio.pause();
} else {
audio.play();
}
});
结果
试着播放音频,然后切换到不同的标签页,然后再返回。
规范
Specification |
---|
HTML Standard # dom-document-visibilitystate |
浏览器兼容性
BCD tables only load in the browser