@@ -13,8 +13,7 @@ import {
13
13
ExpressionNode ,
14
14
ElementTypes ,
15
15
PlainElementNode ,
16
- JSChildNode ,
17
- createSimpleExpression
16
+ JSChildNode
18
17
} from '@vue/compiler-core'
19
18
import {
20
19
isVoidTag ,
@@ -39,67 +38,67 @@ export const enum StringifyThresholds {
39
38
export const stringifyStatic : HoistTransform = ( children , context ) => {
40
39
let nc = 0 // current node count
41
40
let ec = 0 // current element with binding count
42
- const currentEligibleNodes : PlainElementNode [ ] = [ ]
41
+ const currentChunk : PlainElementNode [ ] = [ ]
43
42
44
- for ( let i = 0 ; i < children . length ; i ++ ) {
45
- const child = children [ i ]
46
- const hoisted = getHoistedNode ( child )
47
- if ( hoisted ) {
48
- // presence of hoisted means child must be a plain element Node
49
- const node = child as PlainElementNode
50
- const result = analyzeNode ( node )
51
- if ( result ) {
52
- // node is stringifiable, record state
53
- nc += result [ 0 ]
54
- ec += result [ 1 ]
55
- currentEligibleNodes . push ( node )
56
- continue
57
- }
58
- }
59
-
60
- // we only reach here if we ran into a node that is not stringifiable
61
- // check if currently analyzed nodes meet criteria for stringification.
43
+ const stringifyCurrentChunk = ( currentIndex : number ) : number => {
62
44
if (
63
45
nc >= StringifyThresholds . NODE_COUNT ||
64
46
ec >= StringifyThresholds . ELEMENT_WITH_BINDING_COUNT
65
47
) {
66
48
// combine all currently eligible nodes into a single static vnode call
67
49
const staticCall = createCallExpression ( context . helper ( CREATE_STATIC ) , [
68
50
JSON . stringify (
69
- currentEligibleNodes
70
- . map ( node => stringifyElement ( node , context ) )
71
- . join ( '' )
51
+ currentChunk . map ( node => stringifyElement ( node , context ) ) . join ( '' )
72
52
) ,
73
53
// the 2nd argument indicates the number of DOM nodes this static vnode
74
54
// will insert / hydrate
75
- String ( currentEligibleNodes . length )
55
+ String ( currentChunk . length )
76
56
] )
77
57
// replace the first node's hoisted expression with the static vnode call
78
- replaceHoist ( currentEligibleNodes [ 0 ] , staticCall , context )
58
+ replaceHoist ( currentChunk [ 0 ] , staticCall , context )
79
59
80
- const n = currentEligibleNodes . length
81
- if ( n > 1 ) {
82
- for ( let j = 1 ; j < n ; j ++ ) {
60
+ if ( currentChunk . length > 1 ) {
61
+ for ( let i = 1 ; i < currentChunk . length ; i ++ ) {
83
62
// for the merged nodes, set their hoisted expression to null
84
- replaceHoist (
85
- currentEligibleNodes [ j ] ,
86
- createSimpleExpression ( `null` , false ) ,
87
- context
88
- )
63
+ replaceHoist ( currentChunk [ i ] , null , context )
89
64
}
65
+
90
66
// also remove merged nodes from children
91
- const deleteCount = n - 1
92
- children . splice ( i - n + 1 , deleteCount )
93
- // adjust iteration index
94
- i -= deleteCount
67
+ const deleteCount = currentChunk . length - 1
68
+ children . splice ( currentIndex - currentChunk . length + 1 , deleteCount )
69
+ return deleteCount
95
70
}
96
71
}
72
+ return 0
73
+ }
97
74
75
+ let i = 0
76
+ for ( ; i < children . length ; i ++ ) {
77
+ const child = children [ i ]
78
+ const hoisted = getHoistedNode ( child )
79
+ if ( hoisted ) {
80
+ // presence of hoisted means child must be a plain element Node
81
+ const node = child as PlainElementNode
82
+ const result = analyzeNode ( node )
83
+ if ( result ) {
84
+ // node is stringifiable, record state
85
+ nc += result [ 0 ]
86
+ ec += result [ 1 ]
87
+ currentChunk . push ( node )
88
+ continue
89
+ }
90
+ }
91
+ // we only reach here if we ran into a node that is not stringifiable
92
+ // check if currently analyzed nodes meet criteria for stringification.
93
+ // adjust iteration index
94
+ i -= stringifyCurrentChunk ( i )
98
95
// reset state
99
96
nc = 0
100
97
ec = 0
101
- currentEligibleNodes . length = 0
98
+ currentChunk . length = 0
102
99
}
100
+ // in case the last node was also stringifiable
101
+ stringifyCurrentChunk ( i )
103
102
}
104
103
105
104
const getHoistedNode = ( node : TemplateChildNode ) =>
@@ -116,7 +115,7 @@ const isStringifiableAttr = (name: string) => {
116
115
117
116
const replaceHoist = (
118
117
node : PlainElementNode ,
119
- replacement : JSChildNode ,
118
+ replacement : JSChildNode | null ,
120
119
context : TransformContext
121
120
) => {
122
121
const hoistToReplace = ( node . codegenNode as SimpleExpressionNode ) . hoisted !
0 commit comments