]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
feat: proper static tree skip
authorEvan You <yyx990803@gmail.com>
Tue, 13 Nov 2018 03:42:34 +0000 (22:42 -0500)
committerEvan You <yyx990803@gmail.com>
Tue, 13 Nov 2018 03:42:34 +0000 (22:42 -0500)
packages/runtime-core/src/createRenderer.ts
packages/runtime-core/src/vdom.ts

index 09b7c9cb33a9784916c910fe96dd91aa334e093e..a789c3c116ff266ecaa9b2ce868a05b9f11b62da 100644 (file)
@@ -477,7 +477,18 @@ export function createRenderer(options: RendererOptions) {
     contextVNode: MountedVNode | null,
     isSVG: boolean
   ) {
-    const { flags, tag } = nextVNode
+    const { flags, tag, clonedFrom } = nextVNode
+
+    // cloned vnodes pointing to the same original.
+    // these are hoisted static trees so just skip entirely
+    if (
+      clonedFrom !== null &&
+      (clonedFrom === prevVNode || clonedFrom === prevVNode.clonedFrom)
+    ) {
+      nextVNode.el = prevVNode.el
+      return
+    }
+
     isSVG = isSVG || (flags & VNodeFlags.ELEMENT_SVG) > 0
 
     if (prevVNode.tag !== tag) {
index be222b6700dc8ef6d529ba627971b99fc8f090bc..b44d2c1d778277058a8f48df7241e8c3d49ab192 100644 (file)
@@ -43,6 +43,8 @@ export interface VNode {
   // a consistent handle so that a functional component can be identified
   // by the scheduler
   handle: FunctionalHandle | null
+  // only on cloned vnodes, points to the original cloned vnode
+  clonedFrom: VNode | null
 }
 
 export interface MountedVNode extends VNode {
@@ -99,7 +101,8 @@ export function createVNode(
     el: null,
     parentVNode: null,
     contextVNode: null,
-    handle: null
+    handle: null,
+    clonedFrom: null
   }
   if (childFlags === ChildrenFlags.UNKNOWN_CHILDREN) {
     normalizeChildren(vnode, children)
@@ -339,7 +342,7 @@ export function cloneVNode(vnode: VNode, extraData?: VNodeData): VNode {
         }
       }
     }
-    return createVNode(
+    const cloned = createVNode(
       flags,
       vnode.tag,
       clonedData,
@@ -349,6 +352,8 @@ export function cloneVNode(vnode: VNode, extraData?: VNodeData): VNode {
       vnode.ref,
       vnode.slots
     )
+    cloned.clonedFrom = vnode.clonedFrom || vnode
+    return cloned
   } else if (flags & VNodeFlags.TEXT) {
     return createTextVNode(vnode.children as string)
   } else {