【问题标题】:Web Workers in Chrome v54 run twice as slow when running in an inactive tab在非活动选项卡中运行时,Chrome v54 中的 Web Worker 运行速度要慢两倍
【发布时间】:2016-11-08 05:57:00
【问题描述】:

我有一个使用 setTimeout 播放带有淡入/淡出过渡的音频的 web 应用。众所周知,chrome 和其他浏览器在非活动(或后台)选项卡中运行时会限制 setTimeout 的执行。所以为了解决这个问题,我使用这个脚本 (https://github.com/turuslan/HackTimer) 来修补 Timer API 以使用 Web Worker。这允许音量衰减过渡在后台运行,以便无论选项卡是否处于活动状态,它们都将始终同时执行和完成。这曾经在 chrome 中运行良好,但现在我注意到在 chrome 的 54 版(可能还有更早的版本)中,在非活动选项卡中运行时,Web Worker 的执行速度要慢两倍。这个问题不会发生,并且与 FireFox 甚至 IE11 完美配合!

这是一个 chrome 错误吗?或者它是预期的行为?是否有另一个 解决此问题的方法?我不想要求在单独的窗口中打开 webapp,所以这不是一个选项。

这是一个演示: https://jsfiddle.net/2614xsj8/1/

// Open Chrome console and run this then wait a few seconds to see
// it is executing on time. Then open or switch to a new tab and wait
// a few seconds. Come back to see how much slower the setTimeout
// function was being called even when using HackTimer which patches
// the Timer API to use Web Workers

var rate = 1000;
var start = new Date().getTime();
var func = function() {
  var now = new Date().getTime();
  var time = now - start;
  var status = Math.abs(rate - time) <= 50 ? "on time" : (time / rate) + " times slower";
  console.log("executed in [" + time + "] milliseconds. " + status);
  start = now;
  setTimeout(func, rate);
};
setTimeout(func, rate);
&lt;script src="https://cdn.rawgit.com/turuslan/HackTimer/master/HackTimer.js" type="text/javascript"&gt;&lt;/script&gt;

【问题讨论】:

  • 您是否考虑过使用Audio API?时间更加精细,我认为它不受标签切换的影响。我有一个类似的问题here
  • @jedd.ahyoung 我正在使用音频 API 进行播放等,但没有考虑将其用于计时。我将研究它的计时能力,看看是否适合每隔几毫秒增加/减少音量以实现淡入/淡出过渡。

标签: javascript google-chrome settimeout


【解决方案1】:

使用Task Scheduler 是最好的方法,那么您实际上不是超时或间隔,而是特定日期

但这需要使用服务工作者来代替......这很糟糕。因为那么您的站点也需要被列入白名单才能运行服务人员(因此您的站点需要有效的 SSL 证书)

// https://example.com/serviceworker.js
this.ontask = function(task) {
    alert(task.data.message);
    console.log("Task scheduled at: " + new Date(task.time));
    // From here on we can write the data to IndexedDB, send it to any open windows,
    // display a notification, etc.
}

// https://example.com/webapp.js
function onTaskAdded(task) {
    console.log("Task successfully scheduled.");
}

function onError(error) {
    alert("Sorry, couldn't set the alarm: " + error);
}

navigator.serviceWorker.ready.then(function(serviceWorkerRegistration) {
    serviceWorkerRegistration.taskScheduler.add(Date.now() + (10 * 60000), {
        message: "It's been 10 minutes, your soup is ready!"
    }).then(onTaskAdded, onError);
});

【讨论】:

  • 嗯。幸运的是,我使用的是有效的 SSL 证书,所以这对我来说可能是一个不错的选择。我会试一试,然后发回结果。
  • 这是 w3.org/TR/task-scheduler 代码的精确副本,实际上在 chrome 中无法使用。
猜你喜欢
  • 2018-01-03
  • 1970-01-01
  • 1970-01-01
  • 2012-11-05
  • 2019-12-09
  • 1970-01-01
  • 2014-08-28
  • 1970-01-01
相关资源
最近更新 更多