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

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

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

  • 当选项卡未激活时,ios 5暂停JavaScript
  • setIntervalsetTimeout延迟在选项卡不活动的时候会减less – 看起来像刚刚开始出现的那样,可能会混淆Jasmineunit testing等等。
  • requestAnimationFrame在选项卡不活动时会变慢(合理,不能想到为什么这会影响任何人太多)

我有以下问题:

  • 除了移动浏览器之外,桌面浏览器是否会在选项卡未激活时暂停执行JS? 何时和哪些浏览器?
  • 哪些浏览器减less了setInterval重复? 它只是减less到一个限制或一个百分比? 例如,如果我有一个10ms的重复与5000ms的重复,每个都会受到影响?
  • 如果窗口没有对焦,而不是只是选项卡,是否会发生这些变化? (我想这将是更难以检测,因为它需要OS API。)
  • 是否有任何其他效果不会在活动选项卡中被观察到? 他们可以搞砸了,否则会正确执行(即上述茉莉花testing)?

testing一

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

注意:这个testing是相当CPU的。 IE 9和Opera 12不支持requestAnimationFrame

testinglogging了setIntervalrequestAnimationFrame在不同浏览器中运行所花费的实际时间,并以分布forms给出结果。 您可以更改setInterval的毫秒数,以了解它在不同设置下的运行方式。 setTimeout在延迟方面与setInterval类似。 requestAnimationFrame通常默认为60fps,具体取决于浏览器。 要查看切换到其他选项卡或具有非活动窗口时发生的情况,只需打开页面,切换到其他选项卡并等待一段时间。 它将继续将这些function所需的实际时间logging在非活动选项卡中。

testing二

testing它的另一种方法是使用setIntervalrequestAnimationFrame重复logging时间戳,并在分离的控制台中查看它。 您可以查看当您使标签页或窗口处于非活动状态时,更新的频率(或者是否更新过)。

  • testingsetInterval
  • testingrequestAnimationFrame

结果


当选项卡处于非活动状态时,Chrome会将setInterval的最小时间间隔限制为大约1000毫秒。 如果间隔高于1000毫秒,它将以指定的时间间隔运行。 如果窗口没有对焦就没有关系,只有当您切换到不同的选项卡时,间隔才会受到限制。 当选项卡处于非活动状态时, requestAnimationFrame将暂停。

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

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

火狐
与Chrome类似,当选项卡(而不是窗口)处于非活动状态时,Firefox将setInterval的最小间隔限制为大约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 

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

IE浏览器
IE不限制标签处于非活动状态时的setInterval延迟,但会暂停非活动标签中的requestAnimationFrame 。 这个窗口是不是焦点没关系。

边缘
从边缘14开始, setInterval在非活动标签中的上限为1000ms。 requestAnimationFrame始终在非活动选项卡中暂停。

苹果浏览器
就像Chrome一样,当选项卡处于非活动状态时,Safari会在1000毫秒时限制setIntervalrequestAnimationFrame也暂停。

歌剧
自从Webkit引擎被采用以来,Opera就performance出与Chrome相同的行为。 setInterval的上限为1000毫秒,当选项卡处于非活动状态时, requestAnimationFrame将暂停。

概要

为非活动标签重复间隔:

            setInterval requestAnimationFrame
 
 9-不受影响不受支持
 10个不受影响暂停
 11+> = 1000ms暂停

 火狐
 3-不受影响不受支持
 4不受影响1s
 5+> = 1000毫秒2 n s(n =自不活动以来的帧数)

 IE
 9-不受影响不受支持
 10+不受影响暂停

 边缘
 13  - 不受影响暂停
 14+> = 1000ms暂停

 苹果浏览器
 5-不受影响不支持
 6不受影响暂停
 7+> = 1000ms暂停

 歌剧
 12  - 不受影响不受支持
 15+> = 1000ms暂停

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

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

而且,当整个窗口处于非活动状态时,我并不认为这样做(但似乎很容易调查)。