@@ -39,7 +39,8 @@ export function createHydrationFunctions({
39
39
const hydrateNode = (
40
40
node : Node ,
41
41
vnode : VNode ,
42
- parentComponent : ComponentInternalInstance | null = null
42
+ parentComponent : ComponentInternalInstance | null = null ,
43
+ optimized = false
43
44
) : Node | null => {
44
45
const { type, shapeFlag } = vnode
45
46
vnode . el = node
@@ -49,18 +50,15 @@ export function createHydrationFunctions({
49
50
case Static :
50
51
return node . nextSibling
51
52
case Fragment :
52
- const parent = node . parentNode !
53
- parent . insertBefore ( ( vnode . el = createText ( '' ) ) , node )
54
- const next = hydrateChildren (
55
- node ,
56
- vnode . children as VNode [ ] ,
57
- parentComponent
58
- )
59
- parent . insertBefore ( ( vnode . anchor = createText ( '' ) ) , next )
60
- return next
53
+ return hydrateFragment ( node , vnode , parentComponent , optimized )
61
54
default :
62
55
if ( shapeFlag & ShapeFlags . ELEMENT ) {
63
- return hydrateElement ( node as Element , vnode , parentComponent )
56
+ return hydrateElement (
57
+ node as Element ,
58
+ vnode ,
59
+ parentComponent ,
60
+ optimized
61
+ )
64
62
} else if ( shapeFlag & ShapeFlags . COMPONENT ) {
65
63
// when setting up the render effect, if the initial vnode already
66
64
// has .el set, the component will perform hydration instead of mount
@@ -69,7 +67,7 @@ export function createHydrationFunctions({
69
67
const subTree = vnode . component ! . subTree
70
68
return ( subTree . anchor || subTree . el ) . nextSibling
71
69
} else if ( shapeFlag & ShapeFlags . PORTAL ) {
72
- hydratePortal ( vnode , parentComponent )
70
+ hydratePortal ( vnode , parentComponent , optimized )
73
71
return node . nextSibling
74
72
} else if ( __FEATURE_SUSPENSE__ && shapeFlag & ShapeFlags . SUSPENSE ) {
75
73
// TODO Suspense
@@ -83,7 +81,8 @@ export function createHydrationFunctions({
83
81
const hydrateElement = (
84
82
el : Element ,
85
83
vnode : VNode ,
86
- parentComponent : ComponentInternalInstance | null
84
+ parentComponent : ComponentInternalInstance | null ,
85
+ optimized : boolean
87
86
) => {
88
87
const { props, patchFlag } = vnode
89
88
// skip props & children if this is hoisted static nodes
@@ -123,8 +122,9 @@ export function createHydrationFunctions({
123
122
) {
124
123
hydrateChildren (
125
124
el . firstChild ,
126
- vnode . children as VNode [ ] ,
127
- parentComponent
125
+ vnode ,
126
+ parentComponent ,
127
+ optimized || vnode . dynamicChildren !== null
128
128
)
129
129
}
130
130
}
@@ -133,32 +133,45 @@ export function createHydrationFunctions({
133
133
134
134
const hydrateChildren = (
135
135
node : Node | null ,
136
- vnodes : VNode [ ] ,
137
- parentComponent : ComponentInternalInstance | null
136
+ vnode : VNode ,
137
+ parentComponent : ComponentInternalInstance | null ,
138
+ optimized : boolean
138
139
) : Node | null => {
139
- for ( let i = 0 ; node != null && i < vnodes . length ; i ++ ) {
140
- // TODO can skip normalizeVNode in optimized mode
141
- // (need hint on rendered markup?)
142
- const vnode = ( vnodes [ i ] = normalizeVNode ( vnodes [ i ] ) )
143
- node = hydrateNode ( node , vnode , parentComponent )
140
+ const children = vnode . children as VNode [ ]
141
+ optimized = optimized || vnode . dynamicChildren !== null
142
+ for ( let i = 0 ; node != null && i < children . length ; i ++ ) {
143
+ const vnode = optimized
144
+ ? children [ i ]
145
+ : ( children [ i ] = normalizeVNode ( children [ i ] ) )
146
+ node = hydrateNode ( node , vnode , parentComponent , optimized )
144
147
}
145
148
return node
146
149
}
147
150
151
+ const hydrateFragment = (
152
+ node : Node ,
153
+ vnode : VNode ,
154
+ parentComponent : ComponentInternalInstance | null ,
155
+ optimized : boolean
156
+ ) => {
157
+ const parent = node . parentNode !
158
+ parent . insertBefore ( ( vnode . el = createText ( '' ) ) , node )
159
+ const next = hydrateChildren ( node , vnode , parentComponent , optimized )
160
+ parent . insertBefore ( ( vnode . anchor = createText ( '' ) ) , next )
161
+ return next
162
+ }
163
+
148
164
const hydratePortal = (
149
165
vnode : VNode ,
150
- parentComponent : ComponentInternalInstance | null
166
+ parentComponent : ComponentInternalInstance | null ,
167
+ optimized : boolean
151
168
) => {
152
169
const targetSelector = vnode . props && vnode . props . target
153
170
const target = ( vnode . target = isString ( targetSelector )
154
171
? document . querySelector ( targetSelector )
155
172
: targetSelector )
156
173
if ( target != null && vnode . shapeFlag & ShapeFlags . ARRAY_CHILDREN ) {
157
- hydrateChildren (
158
- target . firstChild ,
159
- vnode . children as VNode [ ] ,
160
- parentComponent
161
- )
174
+ hydrateChildren ( target . firstChild , vnode , parentComponent , optimized )
162
175
}
163
176
}
164
177
0 commit comments