当选项卡或窗口不活动时,浏览器如何暂停/更改Javascript?

2022-08-30 01:40:09

背景:我正在做一些用户界面测试,需要检测人们是否在注意。但是,这个问题页面可见性API无关。

具体来说,我想知道如果当前选项卡在不同的浏览器中不处于活动状态或浏览器窗口不处于活动状态,我的Javascript代码将受到什么影响。到目前为止,我已经挖掘了以下内容:

我有以下问题:

  • 除了移动浏览器之外,桌面浏览器在选项卡未处于活动状态时是否会暂停 JS 执行?何时以及使用哪些浏览器?
  • 哪些浏览器可以减少重复?它只是减少到一个极限还是一个百分比?例如,如果我有一个 10 毫秒的重复与一个 5000 毫秒的重复,那么每个重复将受到怎样的影响?setInterval
  • 如果窗口失焦,而不仅仅是选项卡,是否会发生这些更改?(我想它会更难检测,因为它需要操作系统API。
  • 在活动选项卡中是否还有其他无法观察到的效果?他们是否会搞砸本来可以正确执行的事情(即前面提到的茉莉花测试)?

答案 1

测试一

我专门为此编写了一个测试:
帧速率分布:setInterval vs requestAnimationFrame

注意:此测试占用大量 CPU 资源。requestAnimationFrame 不受 IE 9 和 Opera 12- 的支持。

该测试记录 在不同浏览器中运行 和 所需的实际时间,并以分发的形式为您提供结果。您可以更改 的毫秒数,以查看它在不同设置下的运行方式。 在延迟方面的工作方式与 a 类似。 通常默认为60fps,具体取决于浏览器。要查看切换到其他选项卡或具有非活动窗口时会发生什么情况,只需打开页面,切换到其他选项卡并等待一段时间即可。它将继续在非活动选项卡中记录这些函数所需的实际时间。setIntervalrequestAnimationFramesetIntervalsetTimeoutsetIntervalrequestAnimationFrame

测试二

测试它的另一种方法是使用和分离的控制台重复记录时间戳,并在分离的控制台中查看它。当您使选项卡或窗口处于非活动状态时,您可以查看其更新的频率(或者是否曾经更新过)。setIntervalrequestAnimationFrame

结果

Chrome
Chrome 将标签页处于非活动状态时的最小间隔限制为 1000 毫秒左右。如果间隔大于 1000 毫秒,它将以指定的间隔运行。窗口失焦并不重要,只有当您切换到其他选项卡时,间隔才会受到限制。 当选项卡处于非活动状态时暂停。setIntervalrequestAnimationFrame

// Provides control over the minimum timer interval for background tabs.
const double kBackgroundTabTimerInterval = 1.0;

https://codereview.chromium.org/6546021/patch/1001/2001

Firefox
与Chrome类似,当选项卡(而不是窗口)处于非活动状态时,Firefox将最小间隔限制在1000ms左右。但是,当选项卡处于非活动状态时,运行速度会呈指数级增长,每帧需要 1 秒、2 秒、4 秒、8 秒,依此类推。setIntervalrequestAnimationFrame

// The default shortest interval/timeout we permit
#define DEFAULT_MIN_TIMEOUT_VALUE 4 // 4ms
#define DEFAULT_MIN_BACKGROUND_TIMEOUT_VALUE 1000 // 1000ms

https://hg.mozilla.org/releases/mozilla-release/file/0bf1cadfb004/dom/base/nsGlobalWindow.cpp#l296

Internet Explorer
IE 不限制选项卡处于非活动状态时的延迟,但它会在非活动选项卡中暂停。窗口是否失焦并不重要。setIntervalrequestAnimationFrame

边缘
从边缘 14 开始,在非活动选项卡中的上限为 1000 毫秒。 始终在非活动选项卡中暂停。setIntervalrequestAnimationFrame

Safari
就像Chrome一样,当标签处于非活动状态时,Safari的上限为1000ms。 也已暂停。setIntervalrequestAnimationFrame

Opera
自从采用 Webkit 引擎以来,Opera 表现出与 Chrome 相同的行为。 上限为 1000 毫秒,并在选项卡处于非活动状态时暂停。setIntervalrequestAnimationFrame

总结

非活动选项卡的重复间隔:

           setInterval     requestAnimationFrame
Chrome
9-         not affected    not supported
10         not affected    paused
11+        >=1000ms        paused

Firefox
3-         not affected    not supported
4          not affected    1s
5+         >=1000ms        2ns (n = number of frames since inactivity)

IE
9-         not affected    not supported
10+        not affected    paused

Edge
13-        not affected    paused
14+        >=1000ms        paused

Safari
5-         not affected    not supported
6          not affected    paused
7+         >=1000ms        paused

Opera
12-        not affected    not supported
15+        >=1000ms        paused

答案 2

我观察到的 :在Chrome中的非活动标签上,所有等待少于1000ms的(必须相同)都被四舍五入为1000ms。我认为更长的超时不会被修改。setTimeoutsetInterval

似乎是自Chrome 11Firefox 5.0以来的行为:https://developer.mozilla.org/en-US/docs/DOM/window.setTimeout#Inactive_tabs

此外,当整个窗口处于非活动状态时,我不认为它的行为方式(但似乎很容易调查)。