Suppose I call setTimeout(() => {...}, 1000), i.e, a 1 second wait, but the computer has its internal clock wrong. After 500ms, the OS receive a NTP update, realize its clock was 30 second in the future, and thus set back its clock 30 second. When will my timeout fire? In 500ms, monotonic time; or 30500ms, wall clock time?
If its in 30 second... is there a way to set up a timer that will fire correctly after 500ms as measured with performance.now()?
Do the behavior vary between browser?
Note: of course you'll never get a highly accurate setTimeout, because browser mitigate Spectre and old code rely on a minimum delay, but my question is about the huge jump in time du to a change in the internal clock.
By running the following snippet in different browsers and looking at the behavior when changing the OS clock time in different OSes.
The different tests: Test 1:
Test 2:
Test 3:
Test 4:
Every test that I have ran was repeated 5 times.
const perfor = () => {
console.log(performance.now());
window.requestAnimationFrame(perfor);
}
window.requestAnimationFrame(perfor);
setTimeout(() => {
alert('HI');
}, 30000);
Testing on Windows 10(OS Build 19041.508) with all browsers being a 64-bit build: Test 1:
| setTimeout | perfor |
------------------------------|----------------------|------------|
Firefox 81.0.2 | fired after ~30 secs | kept going |
Firefox 82.0.1 | fired after ~30 secs | kept going |
Google Chrome 86.0.4240.111 | fired after ~30 secs | kept going |
Microsoft Edge 44.19041.423.0 | fired after ~30 secs | kept going |
Test 2:
| setTimeout | perfor |
------------------------------|----------------------|-----------------------------|
Firefox 81.0.2 | fired after ~30 secs | stopped when time rewinded* |
Firefox 82.0.1 | fired after ~30 secs | kept going |
Google Chrome 86.0.4240.111 | fired after ~30 secs | kept going |
Microsoft Edge 44.19041.423.0 | fired after ~30 secs | kept going |
Test 3:
| setTimeout | perfor |
------------------------------|----------------------|-----------------------------|
Firefox 81.0.2 | fired after ~30 secs | stopped when time rewinded* |
Firefox 82.0.1 | fired after ~30 secs | kept going |
Google Chrome 86.0.4240.111 | fired after ~30 secs | kept going |
Microsoft Edge 44.19041.423.0 | fired after ~30 secs | kept going |
Test 4:
| setTimeout | perfor |
------------------------------|----------------------|-----------------------------|
Firefox 81.0.2 | fired after ~30 secs | stopped when time rewinded* |
Firefox 82.0.1 | fired after ~30 secs | kept going |
Google Chrome 86.0.4240.111 | fired after ~30 secs | kept going |
Microsoft Edge 44.19041.423.0 | fired after ~30 secs | kept going |
* In Firefox 81.0.2 the logging of performance.now() stopped when I set the OS time in relativity to the past. So if I set my year, month or day in the future and then set set my year, month or day for me in the future but for the machine now in the past Firefox 81.0.2 will stop with logging the performance.now(). I could not find a reason for why and how this happens and why it is fixed in 82.0.1.
NOTE: I could test Firefox in multiple versions because I had an update.
I invite other users to run these and edit to add there results
performance.now() will show the milliseconds since the tab is opened. This is not effected in Windows 10 by changing the OS clock time.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With