Skip to content

Exception in IE 9 due to unsupported High Resolution Time API / getNow race-condition #9632

Closed
@felixbuenemann

Description

@felixbuenemann

Version

2.6.8

Reproduction link

https://jsfiddle.net/re08ag7z/

Steps to reproduce

When Vue.js is used in IE 9 (or IE 10/11 in IE 9 Emulation Mode), it sometimes crashes with an exception:

[Vue warn]: Error in nextTick: "TypeError: Object doesn't support property or method 'now'"

This seems to be due to the usage of performance.now() which is not supported in IE 9, see:

https://caniuse.com/#feat=high-resolution-time

What is expected?

It should not crash, since IE 9 is a supported browser for Vue 2.x.

What is actually happening?

It crashes sometimes and sometimes it works.


I think the problem is a race-condition in the detection code of getNow:

var getNow = Date.now;
if (inBrowser && getNow() > document.createEvent('Event').timeStamp) {
  getNow = function () { return performance.now(); };
}

It looks like if document.createEvent('Event').timeStamp returns a unix timestamp, the result of this check is unpredictable, and is sometimes true and sometimes false.

Running the following in the IE 11 console when in IE 9 emulation mode sometimes returns true and sometimes false:

Date.now() > document.createEvent('Event').timeStamp

This check can also fail in IE 11 in IE 10 emulation mode, so it probably affects IE 10 as well.

A possible workaround would be to check for something like getNow() > document.createEvent('Event').timeStamp 1000, though that still seems a bit brittle.

In my testing in a Windows 10 VM, the difference for Date.now() - document.createEvent('Event').timeStamp was usually /- 2 ms, but sometimes I also got larger offsets, like Date.now() around 22 ms larger than timeStamp.

This problem could also be influenced by clock correction, when NTP or the VM host corrects the guest time between calls.

Generally comparisons of realtime clocks in computers is error prone and only monotonic timers should be trusted, which is probably one of the reasons why performance.now() was created…

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions