Skip to content

Commit

Permalink
refactor(hydration): move fragment to seaprate function + skip normal…
Browse files Browse the repository at this point in the history
…ization in optimized mode
  • Loading branch information
yyx990803 committed Feb 27, 2020
1 parent 3357ff4 commit 4809325
Showing 1 changed file with 41 additions and 28 deletions.
69 changes: 41 additions & 28 deletions packages/runtime-core/src/hydration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -123,8 +122,9 @@ export function createHydrationFunctions({
) {
hydrateChildren(
el.firstChild,
vnode.children as VNode[],
parentComponent
vnode,
parentComponent,
optimized || vnode.dynamicChildren !== null
)
}
}
Expand All @@ -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)
}
}

Expand Down

0 comments on commit 4809325

Please sign in to comment.