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

And*_*Mao 158 javascript browser

背景:我正在做一些需要检测人们是否注意的用户界面测试.但是,这个问题是不是有关的页面知名度API.

具体来说,我想知道如果在不同的浏览器中当前选项卡未激活或浏览器窗口未激活,我的Javascript代码将如何受到影响.到目前为止,我已经挖出了以下内容:

我有以下问题:

  • 除了移动浏览器之外,当选项卡不活动时,桌面浏览器是否会暂停JS执行?何时和哪些浏览器?
  • 哪些浏览器减少setInterval重复?它只是减少到一个限度或一个百分比?例如,如果我有一个10ms重复而不是5000ms重复,那么每个都会受到怎样的影响?
  • 如果窗口失焦,是否会发生这些变化,而不仅仅是标签?(我想它会更难检测,因为它需要OS API.)
  • 在活动标签中是否还有其他效果?他们会把那些本来可以正确执行的事情弄糟(即前面提到的Jasmine测试)吗?

Ant*_*ony 180

测试一

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

注意:此测试非常占用CPU.requestAnimationFrameIE 9-和Opera 12-不支持.

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

测试二

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

结果

当标签处于非活动状态时,Chrome
Chrome会将最小间隔限制setInterval为大约1000毫秒.如果间隔高于1000毫秒,它将以指定的间隔运行.窗口是否失焦并不重要,只有当您切换到不同的选项卡时才会限制间隔.requestAnimationFrame选项卡处于非活动状态时暂停.

// Provides control over the minimum timer interval for background tabs.
const double kBackgroundTabTimerInterval = 1.0;
Run Code Online (Sandbox Code Playgroud)

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

Firefox
与Chrome类似,setInterval当标签(不是窗口)处于非活动状态时,Firefox将最小间隔限制为大约1000毫秒.但是,requestAnimationFrame当选项卡处于非活动状态时,运行速度会呈指数级增长,每帧占用1s,2s,4s,8s等等.

// The default shortest interval/timeout we permit
#define DEFAULT_MIN_TIMEOUT_VALUE 4 // 4ms
#define DEFAULT_MIN_BACKGROUND_TIMEOUT_VALUE 1000 // 1000ms
Run Code Online (Sandbox Code Playgroud)

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

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

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

Safari
就像Chrome一样,setInterval当标签处于非活动状态时,Safari的上限为1000毫秒.requestAnimationFrame也被暂停了.

Opera
自从采用Webkit引擎以来,Opera表现出与Chrome相同的行为.setInterval上限为1000毫秒,requestAnimationFrame当标签处于非活动状态时暂停.

摘要

重复非活动标签的间隔:

           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

  • 通过在浏览器中打开 url `about:config` 并将 `dom.min_background_timeout_value` 值更改为 1000 以外的值,显然可以更改 Firefox setInterval 最小值。 (2认同)

小智 10

我观察到:在Chrome中的非活动标签上,等待小于1000毫秒的所有setTimeout(必须相同setInterval)都会舍入到1000毫秒.我认为更长的超时不会被修改.

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

此外,当整个窗口处于非活动状态时,我认为它不会这样(但似乎很容易调查).

  • 实际上它与**jQuery**或**Javascript**无关,因为它是内部浏览器实现. (2认同)