]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
wip: defer patchData as nodeOp
authorEvan You <yyx990803@gmail.com>
Tue, 13 Nov 2018 03:07:55 +0000 (22:07 -0500)
committerEvan You <yyx990803@gmail.com>
Tue, 13 Nov 2018 03:07:55 +0000 (22:07 -0500)
packages/runtime-core/src/createRenderer.ts
packages/scheduler/src/index.ts

index 9b9021ce9b66bc74e2bcd762ca910da179686627..82492381a9d1ad1af87260d245930a1d7d105aac 100644 (file)
@@ -105,7 +105,7 @@ export function createRenderer(options: RendererOptions) {
     teardownVNode
   } = options
 
-  function insertOrAppend(
+  function queueInsertOrAppend(
     container: RenderNode,
     newNode: RenderNode,
     refNode: RenderNode | null
@@ -161,10 +161,23 @@ export function createRenderer(options: RendererOptions) {
   ) {
     const { flags, tag, data, children, childFlags, ref } = vnode
     isSVG = isSVG || (flags & VNodeFlags.ELEMENT_SVG) > 0
+    // element creation is not deferred since it doesn't produce
+    // user-affecting side effects until inserted into the DOM
     const el = (vnode.el = platformCreateElement(tag as string, isSVG))
     if (data != null) {
       for (const key in data) {
-        patchData(el, key, null, data[key], null, vnode, isSVG)
+        if (!reservedPropRE.test(key)) {
+          platformPatchData(
+            el,
+            key,
+            null,
+            data[key],
+            null,
+            vnode,
+            isSVG,
+            unmountChildren
+          )
+        }
       }
       if (data.vnodeBeforeMount) {
         data.vnodeBeforeMount(vnode)
@@ -185,7 +198,7 @@ export function createRenderer(options: RendererOptions) {
       }
     }
     if (container != null) {
-      insertOrAppend(container, el, endNode)
+      queueInsertOrAppend(container, el, endNode)
     }
     if (ref) {
       queueEffect(() => {
@@ -330,7 +343,7 @@ export function createRenderer(options: RendererOptions) {
   ) {
     const el = (vnode.el = platformCreateText(vnode.children as string))
     if (container != null) {
-      insertOrAppend(container, el, endNode)
+      queueInsertOrAppend(container, el, endNode)
     }
   }
 
@@ -403,7 +416,7 @@ export function createRenderer(options: RendererOptions) {
 
   // patching ------------------------------------------------------------------
 
-  function patchData(
+  function queuePatchData(
     el: RenderNode | (() => RenderNode),
     key: string,
     prevValue: any,
@@ -412,19 +425,19 @@ export function createRenderer(options: RendererOptions) {
     nextVNode: VNode,
     isSVG: boolean
   ) {
-    if (reservedPropRE.test(key)) {
-      return
+    if (!reservedPropRE.test(key)) {
+      queueNodeOp([
+        platformPatchData,
+        el,
+        key,
+        prevValue,
+        nextValue,
+        preVNode,
+        nextVNode,
+        isSVG,
+        unmountChildren
+      ])
     }
-    platformPatchData(
-      typeof el === 'function' ? el() : el,
-      key,
-      prevValue,
-      nextValue,
-      preVNode,
-      nextVNode,
-      isSVG,
-      unmountChildren
-    )
   }
 
   function patch(
@@ -489,7 +502,7 @@ export function createRenderer(options: RendererOptions) {
           const prevValue = prevDataOrEmpty[key]
           const nextValue = nextDataOrEmpty[key]
           if (prevValue !== nextValue) {
-            patchData(
+            queuePatchData(
               el,
               key,
               prevValue,
@@ -505,7 +518,15 @@ export function createRenderer(options: RendererOptions) {
         for (const key in prevDataOrEmpty) {
           const prevValue = prevDataOrEmpty[key]
           if (prevValue != null && !nextDataOrEmpty.hasOwnProperty(key)) {
-            patchData(el, key, prevValue, null, prevVNode, nextVNode, isSVG)
+            queuePatchData(
+              el,
+              key,
+              prevValue,
+              null,
+              prevVNode,
+              nextVNode,
+              isSVG
+            )
           }
         }
       }
@@ -1092,7 +1113,7 @@ export function createRenderer(options: RendererOptions) {
           }
       }
     } else {
-      insertOrAppend(container, vnode.el as RenderNode, refNode)
+      queueInsertOrAppend(container, vnode.el as RenderNode, refNode)
     }
   }
 
index 73ae5a883248e039e0dbcb1cea32c8d5e110c9ec..79e9a564914e49c47b9c913249e16224b1e15722 100644 (file)
@@ -2,7 +2,7 @@
 
 // A data structure that stores a deferred DOM operation.
 // the first element is the function to call, and the rest of the array
-// stores up to 3 arguments.
+// stores up to 8 arguments.
 type Op = [Function, ...any[]]
 
 // A "job" stands for a unit of work that needs to be performed.
@@ -375,5 +375,11 @@ function commitJob(job: Job) {
 
 function applyOp(op: Op) {
   const fn = op[0]
-  fn(op[1], op[2], op[3])
+  // optimize for more common cases
+  // only patchData needs 8 arguments
+  if (op.length <= 3) {
+    fn(op[1], op[2], op[3])
+  } else {
+    fn(op[1], op[2], op[3], op[4], op[5], op[6], op[7], op[8])
+  }
 }