]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
refactor: cache calls to performance.now
authorEvan You <yyx990803@gmail.com>
Wed, 23 Jan 2019 23:52:05 +0000 (18:52 -0500)
committerEvan You <yyx990803@gmail.com>
Wed, 23 Jan 2019 23:52:05 +0000 (18:52 -0500)
packages/runtime-dom/src/modules/events.ts
packages/runtime-dom/src/ua.ts [deleted file]

index 77fbce8c1e7e46193cc2ae07aea929ed819673dc..11b374545b8760e1c2097c57b3dcda389198428b 100644 (file)
@@ -1,5 +1,3 @@
-import { isChrome } from '../ua'
-
 interface Invoker extends Function {
   value: EventValue
   lastUpdated?: number
@@ -9,6 +7,23 @@ type EventValue = (Function | Function[]) & {
   invoker?: Invoker | null
 }
 
+// async edge case fix requires storing an event listener's attach timestamp
+// to avoid the overhead of repeatedly calling performance.now(), we cache
+// and use the same timestamp for all event listners attached in the same tick.
+let cachedNow: number = 0
+const p = Promise.resolve()
+
+function getNow() {
+  if (cachedNow) {
+    return cachedNow
+  } else {
+    p.then(() => {
+      cachedNow = 0
+    })
+    return (cachedNow = performance.now())
+  }
+}
+
 export function patchEvent(
   el: Element,
   name: string,
@@ -21,9 +36,7 @@ export function patchEvent(
       ;(prevValue as EventValue).invoker = null
       invoker.value = nextValue
       nextValue.invoker = invoker
-      if (isChrome) {
-        invoker.lastUpdated = performance.now()
-      }
+      invoker.lastUpdated = getNow()
     } else {
       el.addEventListener(name, createInvoker(nextValue))
     }
@@ -38,20 +51,18 @@ function createInvoker(value: any) {
   }) as any
   invoker.value = value
   value.invoker = invoker
-  if (isChrome) {
-    invoker.lastUpdated = performance.now()
-  }
+  invoker.lastUpdated = getNow()
   return invoker
 }
 
 function invokeEvents(e: Event, value: EventValue, lastUpdated: number) {
   // async edge case #6566: inner click event triggers patch, event handler
-  // attached to outer element during patch, and triggered again. This only
-  // happens in Chrome as it fires microtask ticks between event propagation.
+  // attached to outer element during patch, and triggered again. This
+  // happens because browsers fire microtask ticks between event propagation.
   // the solution is simple: we save the timestamp when a handler is attached,
   // and the handler would only fire if the event passed to it was fired
   // AFTER it was attached.
-  if (isChrome && e.timeStamp < lastUpdated) {
+  if (e.timeStamp < lastUpdated) {
     return
   }
 
diff --git a/packages/runtime-dom/src/ua.ts b/packages/runtime-dom/src/ua.ts
deleted file mode 100644 (file)
index 62bfee8..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-export const UA = window.navigator.userAgent.toLowerCase()
-export const isEdge = UA.indexOf('edge/') > 0
-export const isChrome = /chrome\/\d+/.test(UA) && !isEdge