From c8041dc6579cbc0d7867ca30135d9bd18ff1225a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Bu=CC=88nemann?= Date: Thu, 7 Mar 2019 20:02:41 +0100 Subject: [PATCH 1/2] fix(scheduler): getNow detection can randomly fail The previous detection code compared time stamps based on Date.now() which are not monotonic, so the check could fail due to clock skew or adjustments. This fix changes the check to compare against performance.now() if it is supported, because it is monotonic (strictly increasing). --- src/core/observer/scheduler.js | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/core/observer/scheduler.js b/src/core/observer/scheduler.js index d78b4d0fee8..87fc9150c1f 100644 --- a/src/core/observer/scheduler.js +++ b/src/core/observer/scheduler.js @@ -47,11 +47,13 @@ let getNow: () => number = Date.now // timestamp can either be hi-res (relative to page load) or low-res // (relative to UNIX epoch), so in order to compare time we have to use the // same timestamp type when saving the flush timestamp. -if (inBrowser && getNow() > document.createEvent('Event').timeStamp) { - // if the low-res timestamp which is bigger than the event timestamp - // (which is evaluated AFTER) it means the event is using a hi-res timestamp, - // and we need to use the hi-res version for event listeners as well. - getNow = () => performance.now() +if (inBrowser && window.performance && typeof performance.now === 'function') { + // if the event timestamp is bigger than the hi-res timestamp + // (which is evaluated AFTER) it means the event is using a lo-res timestamp, + // and we need to use the lo-res version for event listeners as well. + if (document.createEvent('Event').timeStamp <= performance.now()) { + getNow = () => performance.now() + } } /** From 341f6a6d4e21eed20a72c209110043e0da60e59f Mon Sep 17 00:00:00 2001 From: Evan You Date: Sat, 9 Mar 2019 00:57:22 +0800 Subject: [PATCH 2/2] Update scheduler.js --- src/core/observer/scheduler.js | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/core/observer/scheduler.js b/src/core/observer/scheduler.js index 87fc9150c1f..1463fc64ad3 100644 --- a/src/core/observer/scheduler.js +++ b/src/core/observer/scheduler.js @@ -47,13 +47,16 @@ let getNow: () => number = Date.now // timestamp can either be hi-res (relative to page load) or low-res // (relative to UNIX epoch), so in order to compare time we have to use the // same timestamp type when saving the flush timestamp. -if (inBrowser && window.performance && typeof performance.now === 'function') { +if ( + inBrowser && + window.performance && + typeof performance.now === 'function' && + getNow() > document.createEvent('Event').timeStamp +) { // if the event timestamp is bigger than the hi-res timestamp // (which is evaluated AFTER) it means the event is using a lo-res timestamp, // and we need to use the lo-res version for event listeners as well. - if (document.createEvent('Event').timeStamp <= performance.now()) { - getNow = () => performance.now() - } + getNow = () => performance.now() } /**