Skip to content

Commit 3e7f093

Browse files
committed
chore: dont process text/comment node as dynamic
1 parent 25b8fbe commit 3e7f093

File tree

3 files changed

+47
-23
lines changed

3 files changed

+47
-23
lines changed

packages/compiler-ssr/src/ssrCodegenTransform.ts

Lines changed: 42 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -269,8 +269,10 @@ export function processChildrenAsStatement(
269269
return createBlockStatement(childContext.body)
270270
}
271271

272-
const isStaticElement = (c: TemplateChildNode): boolean =>
273-
c.type === NodeTypes.ELEMENT && c.tagType !== ElementTypes.COMPONENT
272+
const isStaticChildNode = (c: TemplateChildNode): boolean =>
273+
(c.type === NodeTypes.ELEMENT && c.tagType !== ElementTypes.COMPONENT) ||
274+
c.type === NodeTypes.TEXT ||
275+
c.type === NodeTypes.COMMENT
274276

275277
/**
276278
* Check if a node should be processed as dynamic.
@@ -289,19 +291,21 @@ function shouldProcessAsDynamic(
289291
node: TemplateChildNode,
290292
): boolean {
291293
// 1. Must be a dynamic node type
292-
if (isStaticElement(node)) return false
294+
if (isStaticChildNode(node)) return false
293295
// 2. Must be inside a parent element
294296
if (!parent.tag) return false
295297

296-
const children = parent.children
298+
const children = parent.children.filter(
299+
child => !(child.type === NodeTypes.TEXT && !child.content.trim()),
300+
)
297301
const len = children.length
298302
const index = children.indexOf(node)
299303

300304
// 3. Check for a static previous sibling
301305
let hasStaticPreviousSibling = false
302306
if (index > 0) {
303307
for (let i = index - 1; i >= 0; i--) {
304-
if (isStaticElement(children[i])) {
308+
if (isStaticChildNode(children[i])) {
305309
hasStaticPreviousSibling = true
306310
break
307311
}
@@ -313,27 +317,47 @@ function shouldProcessAsDynamic(
313317
let hasStaticNextSibling = false
314318
if (index > -1 && index < len - 1) {
315319
for (let i = index + 1; i < len; i++) {
316-
if (isStaticElement(children[i])) {
320+
if (isStaticChildNode(children[i])) {
317321
hasStaticNextSibling = true
318322
break
319323
}
320324
}
321325
}
322326
if (!hasStaticNextSibling) return false
323327

324-
// 5. Check for a consecutive dynamic sibling (immediately before or after)
325-
let hasConsecutiveDynamicNodes = false
326-
if (index > 0 && !isStaticElement(children[index - 1])) {
327-
hasConsecutiveDynamicNodes = true
328+
// 5. Calculate the number and location of continuous dynamic nodes
329+
let dynamicNodeCount = 1 // The current node is counted as one
330+
let prevDynamicCount = 0
331+
let nextDynamicCount = 0
332+
333+
// Count consecutive dynamic nodes forward
334+
for (let i = index - 1; i >= 0; i--) {
335+
if (!isStaticChildNode(children[i])) {
336+
prevDynamicCount++
337+
} else {
338+
break
339+
}
340+
}
341+
342+
// Count consecutive dynamic nodes backwards
343+
for (let i = index + 1; i < len; i++) {
344+
if (!isStaticChildNode(children[i])) {
345+
nextDynamicCount++
346+
} else {
347+
break
348+
}
349+
}
350+
351+
dynamicNodeCount = 1 + prevDynamicCount + nextDynamicCount
352+
353+
// For two consecutive dynamic nodes, mark both as dynamic
354+
if (dynamicNodeCount === 2) {
355+
return prevDynamicCount > 0 || nextDynamicCount > 0
328356
}
329-
if (
330-
!hasConsecutiveDynamicNodes &&
331-
index < len - 1 &&
332-
!isStaticElement(children[index + 1])
333-
) {
334-
hasConsecutiveDynamicNodes = true
357+
// For three or more dynamic nodes, only mark the intermediate nodes as dynamic
358+
else if (dynamicNodeCount >= 3) {
359+
return prevDynamicCount > 0 && nextDynamicCount > 0
335360
}
336361

337-
// Only process as dynamic if all conditions are met
338-
return hasConsecutiveDynamicNodes
362+
return false
339363
}

packages/runtime-core/src/hydration.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ export function createHydrationFunctions(
125125

126126
function nextSibling(node: Node) {
127127
let n = next(node)
128-
// skip dynamic child anchor
128+
// skip dynamic anchors
129129
if (n && isDynamicAnchor(n)) {
130130
n = next(n)
131131
}

packages/runtime-vapor/__tests__/hydration.spec.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -334,13 +334,13 @@ describe('Vapor Mode hydration', () => {
334334
},
335335
)
336336
expect(container.innerHTML).toMatchInlineSnapshot(
337-
`"<div><span></span><!--[[-->foo<!--]]--><!--[[--> <!--]]--><!--[[--> foo <!--]]--><!--[[--> <!--]]--><!--[[-->foo<!--]]--><span></span></div>"`,
337+
`"<div><span></span>foo<!--[[--> foo <!--]]-->foo<span></span></div>"`,
338338
)
339339

340340
data.value = 'bar'
341341
await nextTick()
342342
expect(container.innerHTML).toMatchInlineSnapshot(
343-
`"<div><span></span><!--[[-->bar<!--]]--><!--[[--> <!--]]--><!--[[--> bar <!--]]--><!--[[--> <!--]]--><!--[[-->bar<!--]]--><span></span></div>"`,
343+
`"<div><span></span>bar<!--[[--> bar <!--]]-->bar<span></span></div>"`,
344344
)
345345
})
346346

@@ -439,13 +439,13 @@ describe('Vapor Mode hydration', () => {
439439
},
440440
)
441441
expect(container.innerHTML).toMatchInlineSnapshot(
442-
`"<div><span></span><!--[[--><!--[--><div>foo</div>-foo<!--]--><!--]]--><!--[[--> <!--]]--><!--[[--> foo <!--]]--><!--[[--> <!--]]--><!--[[--><!--[--><div>foo</div>-foo<!--]--><!--]]--><span></span></div>"`,
442+
`"<div><span></span><!--[--><div>foo</div>-foo<!--]--> <!--[[--> foo <!--]]--> <!--[--><div>foo</div>-foo<!--]--><span></span></div>"`,
443443
)
444444

445445
data.value = 'bar'
446446
await nextTick()
447447
expect(container.innerHTML).toMatchInlineSnapshot(
448-
`"<div><span></span><!--[[--><!--[--><div>bar</div>-bar<!--]--><!--]]--><!--[[--> <!--]]--><!--[[--> bar <!--]]--><!--[[--> <!--]]--><!--[[--><!--[--><div>bar</div>-bar<!--]--><!--]]--><span></span></div>"`,
448+
`"<div><span></span><!--[--><div>bar</div>-bar<!--]--> <!--[[--> bar <!--]]--> <!--[--><div>bar</div>-bar<!--]--><span></span></div>"`,
449449
)
450450
})
451451

0 commit comments

Comments
 (0)