1
1
import { warn } from '@vue/runtime-dom'
2
2
import {
3
3
type ChildItem ,
4
- getHydrationState ,
4
+ incrementIndexOffset ,
5
5
insertionAnchor ,
6
6
insertionParent ,
7
7
resetInsertionState ,
@@ -30,9 +30,15 @@ function performHydration<T>(
30
30
// optimize anchor cache lookup
31
31
; ( Comment . prototype as any ) . $fe = undefined
32
32
; ( Node . prototype as any ) . $pns = undefined
33
- ; ( Node . prototype as any ) . $idx = undefined
34
33
; ( Node . prototype as any ) . $uc = undefined
34
+ ; ( Node . prototype as any ) . $idx = undefined
35
35
; ( Node . prototype as any ) . $children = undefined
36
+ ; ( Node . prototype as any ) . $idxMap = undefined
37
+ ; ( Node . prototype as any ) . $prevDynamicCount = undefined
38
+ ; ( Node . prototype as any ) . $anchorCount = undefined
39
+ ; ( Node . prototype as any ) . $appendIndex = undefined
40
+ ; ( Node . prototype as any ) . $indexOffset = undefined
41
+
36
42
isOptimized = true
37
43
}
38
44
enableHydrationNodeLookup ( )
@@ -108,6 +114,7 @@ function adoptTemplateImpl(node: Node, template: string): Node | null {
108
114
isComment ( node . previousSibling ! , '[' )
109
115
) {
110
116
node = node . parentNode ! . insertBefore ( createTextNode ( ' ' ) , node )
117
+ incrementIndexOffset ( node . parentNode ! )
111
118
break
112
119
}
113
120
}
@@ -136,13 +143,19 @@ function adoptTemplateImpl(node: Node, template: string): Node | null {
136
143
137
144
function locateHydrationNodeImpl ( ) : void {
138
145
let node : Node | null
139
- if ( insertionAnchor !== undefined ) {
140
- const hydrationState = getHydrationState ( insertionParent ! ) !
141
- const { prevDynamicCount, logicalChildren, appendAnchor } = hydrationState
146
+ let idxMap : number [ ] | undefined
147
+ if ( insertionAnchor !== undefined && ( idxMap = insertionParent ! . $idxMap ) ) {
148
+ const {
149
+ $prevDynamicCount : prevDynamicCount = 0 ,
150
+ $appendIndex : appendIndex ,
151
+ $indexOffset : indexOffset = 0 ,
152
+ $anchorCount : anchorCount = 0 ,
153
+ } = insertionParent !
142
154
// prepend
143
155
if ( insertionAnchor === 0 ) {
144
- // use prevDynamicCount as index to locate the hydration node
145
- node = logicalChildren [ prevDynamicCount ]
156
+ // use prevDynamicCount as logical index to locate the hydration node
157
+ const realIndex = idxMap ! [ prevDynamicCount ] + indexOffset
158
+ node = insertionParent ! . childNodes [ realIndex ]
146
159
}
147
160
// insert
148
161
else if ( insertionAnchor instanceof Node ) {
@@ -153,36 +166,42 @@ function locateHydrationNodeImpl(): void {
153
166
// consecutive insert operations locate the correct hydration node.
154
167
let { $idx, $uc : usedCount } = insertionAnchor as ChildItem
155
168
if ( usedCount !== undefined ) {
156
- node = logicalChildren [ $idx + usedCount + 1 ]
169
+ const realIndex = idxMap ! [ $idx + usedCount + 1 ] + indexOffset
170
+ node = insertionParent ! . childNodes [ realIndex ]
157
171
usedCount ++
158
172
} else {
159
173
node = insertionAnchor
160
174
// first use of this anchor: it doesn't consume the next child
161
175
// so we track unique anchor appearances for later offset correction
162
- hydrationState . uniqueAnchorCount ++
176
+ insertionParent ! . $anchorCount = anchorCount + 1
163
177
usedCount = 0
164
178
}
165
179
; ( insertionAnchor as ChildItem ) . $uc = usedCount
166
180
}
167
181
// append
168
182
else {
169
- if ( appendAnchor ) {
170
- node = logicalChildren [ ( appendAnchor as ChildItem ) . $idx + 1 ]
183
+ let realIndex : number
184
+ if ( appendIndex !== null && appendIndex !== undefined ) {
185
+ realIndex = idxMap ! [ appendIndex + 1 ] + indexOffset
186
+ node = insertionParent ! . childNodes [ realIndex ]
171
187
} else {
172
- node =
188
+ if ( insertionAnchor === null ) {
173
189
// insertionAnchor is null, indicates no previous static nodes
174
190
// use the first child as hydration node
175
- insertionAnchor === null
176
- ? logicalChildren [ 0 ]
177
- : // insertionAnchor is a number > 0
178
- // indicates how many static nodes precede the node to append
179
- // use it as index to locate the hydration node
180
- logicalChildren [ prevDynamicCount + insertionAnchor ]
191
+ realIndex = idxMap ! [ 0 ] + indexOffset
192
+ node = insertionParent ! . childNodes [ realIndex ]
193
+ } else {
194
+ // insertionAnchor is a number > 0
195
+ // indicates how many static nodes precede the node to append
196
+ // use it as index to locate the hydration node
197
+ realIndex = idxMap ! [ prevDynamicCount + insertionAnchor ] + indexOffset
198
+ node = insertionParent ! . childNodes [ realIndex ]
199
+ }
181
200
}
182
- hydrationState . appendAnchor = node
201
+ insertionParent ! . $appendIndex = ( node as ChildItem ) . $idx
183
202
}
184
203
185
- hydrationState . prevDynamicCount ++
204
+ insertionParent ! . $ prevDynamicCount = prevDynamicCount + 1
186
205
} else {
187
206
node = currentHydrationNode
188
207
if ( insertionParent && ( ! node || node . parentNode !== insertionParent ) ) {
0 commit comments