]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
refactor(hydration): move fragment to seaprate function + skip normalization in optim...
authorEvan You <yyx990803@gmail.com>
Thu, 27 Feb 2020 16:26:39 +0000 (11:26 -0500)
committerEvan You <yyx990803@gmail.com>
Thu, 27 Feb 2020 16:26:39 +0000 (11:26 -0500)
packages/runtime-core/src/hydration.ts

index ffe71ad36099f791db1520d316ded5047cce79f4..844b30a0ea966129b8ac7160f15092f19b63a2a0 100644 (file)
@@ -39,7 +39,8 @@ export function createHydrationFunctions({
   const hydrateNode = (
     node: Node,
     vnode: VNode,
-    parentComponent: ComponentInternalInstance | null = null
+    parentComponent: ComponentInternalInstance | null = null,
+    optimized = false
   ): Node | null => {
     const { type, shapeFlag } = vnode
     vnode.el = node
@@ -49,18 +50,15 @@ export function createHydrationFunctions({
       case Static:
         return node.nextSibling
       case Fragment:
-        const parent = node.parentNode!
-        parent.insertBefore((vnode.el = createText('')), node)
-        const next = hydrateChildren(
-          node,
-          vnode.children as VNode[],
-          parentComponent
-        )
-        parent.insertBefore((vnode.anchor = createText('')), next)
-        return next
+        return hydrateFragment(node, vnode, parentComponent, optimized)
       default:
         if (shapeFlag & ShapeFlags.ELEMENT) {
-          return hydrateElement(node as Element, vnode, parentComponent)
+          return hydrateElement(
+            node as Element,
+            vnode,
+            parentComponent,
+            optimized
+          )
         } else if (shapeFlag & ShapeFlags.COMPONENT) {
           // when setting up the render effect, if the initial vnode already
           // has .el set, the component will perform hydration instead of mount
@@ -69,7 +67,7 @@ export function createHydrationFunctions({
           const subTree = vnode.component!.subTree
           return (subTree.anchor || subTree.el).nextSibling
         } else if (shapeFlag & ShapeFlags.PORTAL) {
-          hydratePortal(vnode, parentComponent)
+          hydratePortal(vnode, parentComponent, optimized)
           return node.nextSibling
         } else if (__FEATURE_SUSPENSE__ && shapeFlag & ShapeFlags.SUSPENSE) {
           // TODO Suspense
@@ -83,7 +81,8 @@ export function createHydrationFunctions({
   const hydrateElement = (
     el: Element,
     vnode: VNode,
-    parentComponent: ComponentInternalInstance | null
+    parentComponent: ComponentInternalInstance | null,
+    optimized: boolean
   ) => {
     const { props, patchFlag } = vnode
     // skip props & children if this is hoisted static nodes
@@ -123,8 +122,9 @@ export function createHydrationFunctions({
       ) {
         hydrateChildren(
           el.firstChild,
-          vnode.children as VNode[],
-          parentComponent
+          vnode,
+          parentComponent,
+          optimized || vnode.dynamicChildren !== null
         )
       }
     }
@@ -133,32 +133,45 @@ export function createHydrationFunctions({
 
   const hydrateChildren = (
     node: Node | null,
-    vnodes: VNode[],
-    parentComponent: ComponentInternalInstance | null
+    vnode: VNode,
+    parentComponent: ComponentInternalInstance | null,
+    optimized: boolean
   ): Node | null => {
-    for (let i = 0; node != null && i < vnodes.length; i++) {
-      // TODO can skip normalizeVNode in optimized mode
-      // (need hint on rendered markup?)
-      const vnode = (vnodes[i] = normalizeVNode(vnodes[i]))
-      node = hydrateNode(node, vnode, parentComponent)
+    const children = vnode.children as VNode[]
+    optimized = optimized || vnode.dynamicChildren !== null
+    for (let i = 0; node != null && i < children.length; i++) {
+      const vnode = optimized
+        ? children[i]
+        : (children[i] = normalizeVNode(children[i]))
+      node = hydrateNode(node, vnode, parentComponent, optimized)
     }
     return node
   }
 
+  const hydrateFragment = (
+    node: Node,
+    vnode: VNode,
+    parentComponent: ComponentInternalInstance | null,
+    optimized: boolean
+  ) => {
+    const parent = node.parentNode!
+    parent.insertBefore((vnode.el = createText('')), node)
+    const next = hydrateChildren(node, vnode, parentComponent, optimized)
+    parent.insertBefore((vnode.anchor = createText('')), next)
+    return next
+  }
+
   const hydratePortal = (
     vnode: VNode,
-    parentComponent: ComponentInternalInstance | null
+    parentComponent: ComponentInternalInstance | null,
+    optimized: boolean
   ) => {
     const targetSelector = vnode.props && vnode.props.target
     const target = (vnode.target = isString(targetSelector)
       ? document.querySelector(targetSelector)
       : targetSelector)
     if (target != null && vnode.shapeFlag & ShapeFlags.ARRAY_CHILDREN) {
-      hydrateChildren(
-        target.firstChild,
-        vnode.children as VNode[],
-        parentComponent
-      )
+      hydrateChildren(target.firstChild, vnode, parentComponent, optimized)
     }
   }