当前位置: 首页 > 知识库问答 >
问题:

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

羊舌成周
2023-03-14

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

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

  • ios 5在选项卡不活动时暂停javascript

我有以下问题:

  • 除了移动浏览器之外,桌面浏览器是否在选项卡不活动时暂停JS执行?何时以及哪些浏览器?
  • 哪些浏览器减少了setIntervalrepeat?它只是减少到一个限度还是一个百分比?例如,如果我有10毫秒的重复和5000毫秒的重复,每个重复会受到什么影响?
  • 如果窗口不对焦,而不仅仅是选项卡,是否会发生这些更改?(我想这会更难检测,因为它需要操作系统API。)
  • 是否存在在活动选项卡中无法观察到的任何其他效果?他们会不会把本来可以正确执行的事情弄糟(即前面提到的Jasmine测试)

共有3个答案

龙令
2023-03-14

一个更新的答案补充了这些:在chrome 78.0.3904.108上,我注意到所有这些超时(不仅仅是那些低于1000毫秒的超时)在我移动到另一个选项卡时比预期的要长一点,然后返回。我看到的行为被更正确地描述为“非活动选项卡上的所有超时可能会延迟一些额外的时间,最多1000毫秒。”尝试运行以下命令并切换到另一个选项卡!

let timeouts = [ 500, 1000, 2000, 3000, 10000 ];

let minExcess = document.getElementsByClassName('minExcess')[0];

timeouts.forEach(ms => {
  let elem = document.getElementsByClassName(`t${ms}`)[0];
  let cnt = 0;
  
  let lastMs = +new Date();
  let f = () => {
    let curMs = +new Date();
    let disp = document.createElement('p');
    let net = curMs - lastMs;
    lastMs = curMs;
        
    setTimeout(f, ms);
    if (minExcess.value && (net - ms) < parseInt(minExcess.value)) return;
    
    disp.innerText = `${net},`;
    elem.appendChild(disp);
    if (++cnt > 10) elem.firstElementChild.remove();
    
  };
  setTimeout(f, ms);
  
});
body { font-size: 80%; }
div {
  max-height: 80px;
  overflow-x: auto;
  background-color: rgba(0, 0, 0, 0.1);
  margin-bottom: 2px;
  white-space: nowrap;
}
p { margin: 0; }
div > p {
  margin: 0;
  display: inline-block;
  vertical-align: top;
  margin-right: 2px;
}
input { margin: 0 0 10px 0; }
.t500:before { display: block; content: '500ms'; font-weight: bold; }
.t1000:before { display: block; content: '1000ms'; font-weight: bold; }
.t2000:before { display: block; content: '2000ms'; font-weight: bold; }
.t3000:before { display: block; content: '3000ms'; font-weight: bold; }
.t10000:before { display: block; content: '10000ms'; font-weight: bold; }
<p>Ignore any values delayed by less than this amount:</p>
<input type="text" class="minExcess" value="200" pattern="^[0-9]*$"/>
<div class="timeout t500"></div>
<div class="timeout t1000"></div>
<div class="timeout t2000"></div>
<div class="timeout t3000"></div>
<div class="timeout t10000"></div>
盛辰沛
2023-03-14

我观察到:在Chrome的非活动选项卡上,所有等待时间小于1000ms的setTimeout(必须与setInterval相同)都四舍五入为1000ms。我认为更长的超时时间不会被修改。

似乎是Chrome11和火狐5.0以来的行为:https://developer.mozilla.org/en-US/docs/DOM/window.setTimeout#Inactive_tabs

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

宗政文彬
2023-03-14

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

注意:此测试需要大量CPU 请求动画帧。

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

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

  • 测试setInterval

当选项卡处于非活动状态时,Chrome将setInterval的最小间隔限制在1000ms左右。如果间隔大于1000ms,则将以指定的间隔运行。窗口是否失焦无关紧要,只有切换到其他选项卡时,间隔才会受到限制<当选项卡处于非活动状态时,代码>请求动画帧暂停。

// 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将setInterval的最小间隔限制在当选项卡(而不是窗口)处于非活动状态时的1000ms左右。然而,当选项卡处于非活动状态时,请求动画帧的运行速度会呈指数级下降,每个帧需要1秒、2秒、4秒、8秒等等。

// 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不会限制setInterval中的延迟,但会在非活动选项卡中暂停requestAnimationFrame。窗口是否失焦并不重要。

边缘
从边缘14开始,setInterval在非活动选项卡中上限为1000ms<代码>请求动画帧始终在非活动选项卡中暂停。

Safari
与Chrome一样,当选项卡处于非活动状态时,Safari将setInterval设置为1000ms<代码>请求动画帧也暂停。

setInterval的上限为1000ms,并且当选项卡处于非活动状态时,请求动画框架被暂停。

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

           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
 类似资料:
  • 问题内容: 背景:我正在做一些用户界面测试,这些测试需要检测人们是否在关注。 具体来说,我想知道如果当前的选项卡处于非活动状态,或者浏览器窗口处于非活动状态,那么在不同的浏览器中,我的Javascript代码将受到什么影响。到目前为止,我已经挖掘了以下内容: 我有以下问题: 除了移动浏览器以外,当选项卡处于非活动状态时,桌面浏览器是否会暂停JS执行?什么时候使用哪些浏览器? 哪些浏览器减少重复次数

  • 问题内容: 我想在网页上创建一个链接,该链接将关闭浏览器中当前活动的选项卡,而不关闭浏览器中的其他选项卡。 当用户单击关闭链接时,将出现一条警告消息,要求用户使用两个按钮“是”和“否”进行确认。如果用户单击“是”,则关闭该页面,如果“否”,则不执行任何操作。 怎么做到呢?有什么建议么? 问题答案: 您将需要Javascript来执行此操作。用途: 注意: 隐含当前选项卡。这等效于: 或者您可以指定

  • 本文向大家介绍关闭浏览器窗口/选项卡时如何删除localStorage项目?,包括了关闭浏览器窗口/选项卡时如何删除localStorage项目?的使用技巧和注意事项,需要的朋友参考一下 要在浏览器关闭时清除localStorage数据,可以使用window.onunload事件检查选项卡关闭。 假设为了这个示例,您有一个名为MyStorage的本地存储对象作为全局对象。然后您可以编写一个事件处理

  • 我试图在Chrome中使用Webdriver 2.0添加一个新选项卡,但无法获得结果。我关注了不同论坛上提供的几个答案。由于我对java非常陌生,而且可用的答案更具体到java脚本,因此我发布了这个查询,以尽可能获得一个简单的解决方案。 以下语句不触发任何操作,但Selenium中的结果显示通过。driver.find元素(By.tag名称("body")). sendKeys(Keys.控制"t

  • 我已通过以下方式在我的nodejs服务器上实施了CSRF攻击预防— 登录时的用户收到CSRF令牌和cookie(基于JWT的令牌存储在cookie中)。CSRF令牌是使用 每当用户发出请求(GET或POST)时,我都会将客户端发送的cookie和csrf令牌(在标题中)与服务器上存储的cookie和csrf令牌进行比较,应用程序工作正常 但是,当登录用户打开新选项卡或新浏览器窗口时,客户端具有co

  • 问题内容: 我的JavaScript会定期进行活动。当用户不查看站点时(即窗口或选项卡没有焦点),最好不要运行。 有没有办法使用JavaScript做到这一点? 我的参考点:如果您使用的窗口未激活,则Gmail聊天会播放声音。 问题答案: 自从最初编写此答案以来,新的规范已达到推荐状态。现在,页面可见性API使我们能够更准确地检测页面何时向用户隐藏。 当前的浏览器支持: hrome 13+ Int