refactor(hydration): move fragment to seaprate function + skip normalization in optimized mode
This commit is contained in:
parent
3357ff438c
commit
4809325c07
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user