3

If I write a javascript code what uses setTimeout/setInterval, time will not be valid on Chrome if the related page isn't active. To demonstrate, just simply create an html file with a js code like this:

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

Open page several time, and you'll see that if a page is not active, the title will increment only in abount 2 sec, instead of 250ms. It is a very critical issue in my development. Does anyone know how to evade it? A simple Chrome options could be enought too if there is.

Just to mark it as not duplicate: It is not for animations, it is for background workings. The provided example is very accurate! I need to run script in very accurately and do operations fastly in backgrounded tabs. I know, 99,9999% of people does not need it...

cncDAni3
  • 53
  • 1
  • 8
  • 1
    What exactly is critical about this? You might want to have a look at [How to create an accurate timer in javascript?](https://stackoverflow.com/questions/29971898/how-to-create-an-accurate-timer-in-javascript/29972322) – Bergi Aug 17 '17 at 22:56
  • Well I need it in different places. Main reason: I need to run a JS code in millisec-accurate, once on an inactive page. Now it miss seconds! Secundary, there as working scripts which should have run fast, like 1 operaction/100ms, but it works only 1-2 sec/operation (if working page is not active) – cncDAni3 Aug 18 '17 at 08:52
  • That's just what you *want*, not the reason for it. But I second Derek: a browser is not a RTOS. If you need to do accurate heavy lifting, do it elsewhere - either on the server, or in native application on the client. – Bergi Aug 18 '17 at 09:13
  • So if you were a vendor, will you ask every people "why do you need this?". Reason is simple: for game-controls. Timing attacks, making bots to works smootly. It works great with other browsers, but could be good to works in Chrome too. – cncDAni3 Aug 18 '17 at 15:35
  • Yes of course, one needs to understand what people's actual problems are. Previously you were only telling us that [you want a faster horse](https://en.wikiquote.org/wiki/Henry_Ford#Misattributed) :-) For your case, I would recommend to put timing-sensitive things on the server (so that they even work when people close their tabs), if you're coding clientside bots because you have no control over the server see the duplicate – Bergi Aug 18 '17 at 17:50

3 Answers3

2

Neither function is considered accurate by intention. You never should rely on provided timespans. This inaccuracy can be stressed to some amount by browser when your page isn't visible.

Actually it doesn't make sense to keep working in background using a regular webpage. If you really need to do that try some WebWorker instead. The webpage is for user interaction ... user interaction does not happen in background by intention. Processing things in background is best put in a worker thread. So, it's all about runtime context matching code's conceptual intention.

Thomas Urban
  • 4,649
  • 26
  • 32
1

Adding to what cepharum has, it is impossible to guarantee that your code will be execute every 250ms exactly. Chrome is not a real time operating system, and neither is your code. Depending on the implementation of the interpreter, it may even experience drifts and delays.

With that being said, if you only want to reduce the delay, you can use a worker to trick the system by creating a new thread that will not have its refresh rate limited:

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/

Derek 朕會功夫
  • 92,235
  • 44
  • 185
  • 247
0

I ran into the same issue before, the way I solved it was to use math to calculate the time difference, instead of rely on the setInterval being reliable. E.g.

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);
engineforce
  • 2,840
  • 1
  • 23
  • 17
  • Yes, I already use this trick but it will still check time only once in a sec or two... Not accurate. – cncDAni3 Aug 18 '17 at 09:07