【问题标题】:Chrome slows down javascript if page is not active [duplicate]如果页面不活动,Chrome 会减慢 javascript [重复]
【发布时间】:2018-01-26 11:42:22
【问题描述】:

如果我编写了一个使用 setTimeout/setInterval 的 javascript 代码,如果相关页面未处于活动状态,Chrome 上的时间将无效。 为了演示,只需简单地创建一个带有 js 代码的 html 文件,如下所示:

<script>
    var title = 1;
    setInterval(function(){document.title = "X:"+title; title+=1}, 250);
</script>

多次打开页面,您会看到如果页面未处于活动状态,标题只会在大约 2 秒内增加,而不是 250 毫秒。这是我发展过程中非常关键的问题。 有谁知道如何避免它?如果有的话,一个简单的 Chrome 选项也足够了。

只是为了将其标记为不重复:它不是用于动画,而是用于后台工作。提供的示例非常准确!我需要非常准确地运行脚本并在后台选项卡中快速执行操作。我知道,99,9999% 的人不需要它...

【问题讨论】:

  • 这到底是什么关键?你可能想看看How to create an accurate timer in javascript?
  • 嗯,我在不同的地方需要它。主要原因:我需要在非活动页面上以毫秒精度运行 JS 代码。现在它错过了几秒钟!次要的,作为工作脚本应该运行得很快,比如 1 个操作/100 毫秒,但它只工作 1-2 秒/操作(如果工作页面不活动)
  • 这正是您想要的,而不是它的原因。但我赞同 Derek:浏览器不是 RTOS。如果您需要进行准确的繁重工作,请在其他地方进行 - 无论是在服务器上,还是在客户端的本机应用程序中。
  • 所以如果你是一个供应商,你会问每个人“你为什么需要这个?”。原因很简单:用于游戏控制。定时攻击,使机器人工作顺利。它适用于其他浏览器,但也适用于 Chrome。
  • 是的,当然,我们需要了解人们的实际问题是什么。以前您只告诉我们you want a faster horse :-) 对于您的情况,如果您正在编写客户端机器人,我建议将时间敏感的东西放在服务器上(这样它们甚至可以在人们关闭标签时工作),因为您无法控制服务器查看副本

标签: javascript performance google-chrome settimeout setinterval


【解决方案1】:

这两个函数都被认为是不准确的。你永远不应该依赖提供的时间跨度。当您的页面不可见时,浏览器可能会在一定程度上强调这种不准确性。

实际上,使用常规网页继续在后台工作是没有意义的。如果您真的需要这样做,请尝试使用一些 WebWorker。该网页用于用户交互......用户交互不会有意在后台发生。在后台处理事情最好放在工作线程中。所以,这一切都与运行时上下文匹配代码的概念意图有关。

【讨论】:

    【解决方案2】:

    除了 cepharum 之外,无法保证您的代码每 250 毫秒准确执行一次。 Chrome 不是real time operating system,您的代码也不是。根据解释器的实现,它甚至可能会出现漂移和延迟。

    话虽如此,如果你只想减少延迟,你可以通过创建一个不会限制其刷新率的新线程来使用工作线程来欺骗系统:

    function createWorker(main){
        var blob = new Blob(
            ["(" + main.toString() + ")(self)"],
            {type: "text/javascript"}
        );
        return new Worker(window.URL.createObjectURL(blob));
    }
    
    // Worker
    var worker = createWorker(function(self){
        setInterval(function(){
            self.postMessage(Date.now());
        }, 250);
    });
    worker.onmessage = function(e) {
        console.log("Worker: " + e.data);
    }
    

    https://jsfiddle.net/DerekL/ouzcdh9g/

    【讨论】:

    • 干得好!但不适合我。 worker.onmessage = function(e) { document.title = "X:"+title; title+=1 } 这样做仍然会产生相同的结果
    • 我会假设在这种情况下 Chrome 会限制它更新文档标题的频率。
    • :哦,这是真的!惊人的!非常感谢!所以它真的是重复的,它只是一个错误的例子:)。非常感谢!
    • 更新:也适用于标题更新。我可能只是之前搞砸了一些事情:(
    • @cncDAni3 很高兴听到。
    【解决方案3】:

    我之前遇到过同样的问题,我解决它的方法是使用数学来计算时间差,而不是依赖 setInterval 是否可靠。例如

    var title = 1;
    var tickTime = (new Date()).getTime();
    setInterval(function(){
        var now = (new Date()).getTime();
        document.title = "X:"+title; 
        // you can adjust the math calculation below to 
        // meet your requirements
        title+= (now - tickTime)/250;
        tickTime = now;
    }, 250);
    

    【讨论】:

    • 是的,我已经使用了这个技巧,但它仍然会在一两秒内检查一次时间......不准确。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-11-17
    • 1970-01-01
    • 1970-01-01
    • 2013-05-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多