From: daiwei Date: Wed, 13 Aug 2025 09:53:14 +0000 (+0800) Subject: chore: don't add anchor if children are only one block node X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=301db7518711ec09d94769052ce2b7702080e264;p=thirdparty%2Fvuejs%2Fcore.git chore: don't add anchor if children are only one block node --- diff --git a/packages/compiler-ssr/__tests__/ssrVaporAnchors.spec.ts b/packages/compiler-ssr/__tests__/ssrVaporAnchors.spec.ts index d530ee1f4c..50657f3734 100644 --- a/packages/compiler-ssr/__tests__/ssrVaporAnchors.spec.ts +++ b/packages/compiler-ssr/__tests__/ssrVaporAnchors.spec.ts @@ -25,7 +25,7 @@ describe('insertion anchors', () => { { vapor: true }, ), ).toMatchInlineSnapshot(` - "\`\`) + "\`\`) _ssrRenderVNode(_push, _createVNode(_resolveDynamicComponent('div'), null, { default: _withCtx((_, _push, _parent, _scopeId) => { if (_push) { @@ -50,7 +50,7 @@ describe('insertion anchors', () => { }), _: 1 /* STABLE */ }), _parent) - _push(\`\`" + _push(\`\`" `) }) @@ -81,7 +81,7 @@ describe('insertion anchors', () => { { vapor: true }, ), ).toMatchInlineSnapshot(` - "\`\`) + "\`\`) _ssrRenderVNode(_push, _createVNode(_resolveDynamicComponent('div'), null, { default: _withCtx((_, _push, _parent, _scopeId) => { if (_push) { @@ -108,7 +108,7 @@ describe('insertion anchors', () => { }), _: 3 /* FORWARDED */ }), _parent) - _push(\`\`" + _push(\`\`" `) }) @@ -155,7 +155,7 @@ describe('insertion anchors', () => { { vapor: true }, ), ).toMatchInlineSnapshot(` - "\`\`) + "\`\`) _ssrRenderVNode(_push, _createVNode(_resolveDynamicComponent('div'), null, { default: _withCtx((_, _push, _parent, _scopeId) => { if (_push) { @@ -197,7 +197,7 @@ describe('insertion anchors', () => { }), _: 1 /* STABLE */ }), _parent) - _push(\`\`" + _push(\`\`" `) }) @@ -283,7 +283,7 @@ describe('insertion anchors', () => { { vapor: true }, ), ).toMatchInlineSnapshot(` - "\`\`) + "\`\`) _ssrRenderVNode(_push, _createVNode(_resolveDynamicComponent('div'), null, { default: _withCtx((_, _push, _parent, _scopeId) => { if (_push) { @@ -370,7 +370,7 @@ describe('insertion anchors', () => { }), _: 1 /* STABLE */ }), _parent) - _push(\`\`" + _push(\`\`" `) }) @@ -388,7 +388,7 @@ describe('insertion anchors', () => { { vapor: true }, ), ).toMatchInlineSnapshot(` - "\`\`) + "\`\`) _ssrRenderVNode(_push, _createVNode(_resolveDynamicComponent(_ctx.tag), null, { default: _withCtx((_, _push, _parent, _scopeId) => { if (_push) { @@ -426,7 +426,7 @@ describe('insertion anchors', () => { }), _: 1 /* STABLE */ }), _parent) - _push(\`\`" + _push(\`\`" `) }) @@ -455,7 +455,7 @@ describe('insertion anchors', () => { { vapor: true }, ), ).toMatchInlineSnapshot(` - "\`\`) + "\`\`) _ssrRenderVNode(_push, _createVNode(_resolveDynamicComponent('div'), null, { default: _withCtx((_, _push, _parent, _scopeId) => { if (_push) { @@ -480,7 +480,7 @@ describe('insertion anchors', () => { }), _: 1 /* STABLE */ }), _parent) - _push(\`\`" + _push(\`\`" `) }) }) @@ -544,7 +544,7 @@ describe('insertion anchors', () => { }, ), ).toMatchInlineSnapshot(` - "\`\`) + "\`\`) _ssrRenderVNode(_push, _createVNode(_resolveDynamicComponent('div'), null, { default: _withCtx((_, _push, _parent, _scopeId) => { if (_push) { @@ -575,7 +575,7 @@ describe('insertion anchors', () => { }), _: 1 /* STABLE */ }), _parent) - _push(\`\`" + _push(\`\`" `) }) }) @@ -595,7 +595,7 @@ describe('block anchors', () => { }, ), ).toMatchInlineSnapshot(` - "\`\`) + "\`\`) _ssrRenderVNode(_push, _createVNode(_resolveDynamicComponent(_ctx.tag), null, { default: _withCtx((_, _push, _parent, _scopeId) => { if (_push) { @@ -638,7 +638,7 @@ describe('block anchors', () => { }), _: 1 /* STABLE */ }), _parent) - _push(\`\`" + _push(\`\`" `) }) @@ -655,7 +655,7 @@ describe('block anchors', () => { }, ), ).toMatchInlineSnapshot(` - "\`\`) + "\`\`) _ssrRenderVNode(_push, _createVNode(_resolveDynamicComponent(_ctx.tag), null, { default: _withCtx((_, _push, _parent, _scopeId) => { if (_push) { @@ -700,7 +700,7 @@ describe('block anchors', () => { }), _: 1 /* STABLE */ }), _parent) - _push(\`\`" + _push(\`\`" `) }) @@ -715,7 +715,7 @@ describe('block anchors', () => { }, ), ).toMatchInlineSnapshot(` - "\`\`) + "\`\`) _ssrRenderVNode(_push, _createVNode(_resolveDynamicComponent(_ctx.tag), null, { default: _withCtx((_, _push, _parent, _scopeId) => { if (_push) { @@ -739,7 +739,7 @@ describe('block anchors', () => { }), _: 1 /* STABLE */ }), _parent) - _push(\`\`" + _push(\`\`" `) }) @@ -771,7 +771,7 @@ describe('block anchors', () => { { vapor: true }, ), ).toMatchInlineSnapshot(` - "\`\`) + "\`\`) _ssrRenderVNode(_push, _createVNode(_resolveDynamicComponent(_ctx.tag), null, { default: _withCtx((_, _push, _parent, _scopeId) => { if (_push) { @@ -790,7 +790,7 @@ describe('block anchors', () => { }), _: 3 /* FORWARDED */ }), _parent) - _push(\`\`" + _push(\`\`" `) }) @@ -805,27 +805,25 @@ describe('block anchors', () => { { vapor: true }, ), ).toMatchInlineSnapshot(` - "\`\`) + "\`\`) _ssrRenderVNode(_push, _createVNode(_resolveDynamicComponent("tag"), null, { default: _withCtx((_, _push, _parent, _scopeId) => { if (_push) { - _push(\`\`) + _push(\`\`) _ssrRenderVNode(_push, _createVNode(_resolveDynamicComponent("foo"), null, null), _parent, _scopeId) - _push(\`\`) + _push(\`\`) } else { return [ _createVNode("div", null, [ - _createCommentVNode("[a"), (_openBlock(), _createBlock(_resolveDynamicComponent("foo"))), - _createCommentVNode("dynamic-component"), - _createCommentVNode("a]") + _createCommentVNode("dynamic-component") ]) ] } }), _: 1 /* STABLE */ }), _parent) - _push(\`\`" + _push(\`\`" `) }) }) diff --git a/packages/compiler-ssr/src/ssrCodegenTransform.ts b/packages/compiler-ssr/src/ssrCodegenTransform.ts index fc32850e7e..79a3738df3 100644 --- a/packages/compiler-ssr/src/ssrCodegenTransform.ts +++ b/packages/compiler-ssr/src/ssrCodegenTransform.ts @@ -280,9 +280,11 @@ export function processChildrenAsStatement( export function processBlockNodeAnchor(children: TemplateChildNode[]): void { let prevBlocks: (TemplateChildNode & { anchor?: string })[] = [] let hasStaticNode = false + let blockCount = 0 for (const child of children) { if (isBlockNode(child)) { prevBlocks.push(child) + blockCount++ } if (isStaticNode(child)) { @@ -304,7 +306,9 @@ export function processBlockNodeAnchor(children: TemplateChildNode[]): void { } } - if (prevBlocks.length) { + // When there is only one block node, no anchor is needed, + // firstChild is used as the hydration node + if (prevBlocks.length && !(blockCount === 1 && !hasStaticNode)) { // append anchor prevBlocks.forEach(child => (child.anchor = BLOCK_APPEND_ANCHOR_LABEL)) } diff --git a/packages/compiler-vapor/__tests__/__snapshots__/compile.spec.ts.snap b/packages/compiler-vapor/__tests__/__snapshots__/compile.spec.ts.snap index 103e174e99..f11bfbcc6f 100644 --- a/packages/compiler-vapor/__tests__/__snapshots__/compile.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/__snapshots__/compile.spec.ts.snap @@ -38,7 +38,7 @@ export function render(_ctx) { "default": () => { const n0 = _createIf(() => (true), () => { const n3 = t0() - _setInsertionState(n3, null) + _setInsertionState(n3) const n2 = _createComponentWithFallback(_component_Bar) _withVaporDirectives(n2, [[_directive_hello, void 0, void 0, { world: true }]]) return n3 @@ -220,7 +220,7 @@ export function render(_ctx) { const _component_Comp = _resolveComponent("Comp") const n3 = t0() const n1 = _child(n3) - _setInsertionState(n1, null) + _setInsertionState(n1) const n0 = _createSlot("default", null) _setInsertionState(n3, null) const n2 = _createComponentWithFallback(_component_Comp) diff --git a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vFor.spec.ts.snap b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vFor.spec.ts.snap index e7745851e5..09329d2e9c 100644 --- a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vFor.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vFor.spec.ts.snap @@ -87,7 +87,7 @@ const t1 = _template("
", true) export function render(_ctx) { const n0 = _createFor(() => (_ctx.list), (_for_item0) => { const n5 = t1() - _setInsertionState(n5, null) + _setInsertionState(n5) const n2 = _createFor(() => (_for_item0.value), (_for_item1) => { const n4 = t0() const x4 = _child(n4, -1) diff --git a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vOnce.spec.ts.snap b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vOnce.spec.ts.snap index 4ca745ef0f..b6107d5a1a 100644 --- a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vOnce.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vOnce.spec.ts.snap @@ -42,7 +42,7 @@ const t0 = _template("
", true) export function render(_ctx) { const _component_Comp = _resolveComponent("Comp") const n1 = t0() - _setInsertionState(n1, null) + _setInsertionState(n1) const n0 = _createComponentWithFallback(_component_Comp, { id: () => (_ctx.foo) }, null, null, true) return n1 }" diff --git a/packages/compiler-vapor/src/transforms/transformChildren.ts b/packages/compiler-vapor/src/transforms/transformChildren.ts index e4dcd4d9f3..1ad8dae5ed 100644 --- a/packages/compiler-vapor/src/transforms/transformChildren.ts +++ b/packages/compiler-vapor/src/transforms/transformChildren.ts @@ -60,11 +60,13 @@ export const transformChildren: NodeTransform = (node, context) => { function processDynamicChildren(context: TransformContext) { let prevDynamics: IRDynamicInfo[] = [] let hasStaticTemplate = false + let dynamicCount = 0 const children = context.dynamic.children for (const [index, child] of children.entries()) { if (child.flags & DynamicFlag.INSERT) { prevDynamics.push(child) + dynamicCount++ } if (!(child.flags & DynamicFlag.NON_TEMPLATE)) { @@ -84,7 +86,13 @@ function processDynamicChildren(context: TransformContext) { } if (prevDynamics.length) { - registerInsertion(prevDynamics, context, -2 /* append */) + registerInsertion( + prevDynamics, + context, + // When there is only one dynamic node, no anchor is needed, + // firstChild is used as the hydration node + dynamicCount === 1 && !hasStaticTemplate ? undefined : -2 /* append */, + ) } } diff --git a/packages/runtime-vapor/__tests__/hydration.spec.ts b/packages/runtime-vapor/__tests__/hydration.spec.ts index b501f1a580..ba32291817 100644 --- a/packages/runtime-vapor/__tests__/hydration.spec.ts +++ b/packages/runtime-vapor/__tests__/hydration.spec.ts @@ -1354,11 +1354,7 @@ describe('Vapor Mode hydration', () => { data, ) expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot( - ` - "
- foo -
" - `, + `"
foo
"`, ) data.value = false @@ -1731,10 +1727,8 @@ describe('Vapor Mode hydration', () => { expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot( ` "
-
true
-true- - -
" + " `, ) @@ -1743,10 +1737,8 @@ describe('Vapor Mode hydration', () => { expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot( ` "
- - -
" + " `, ) @@ -1754,10 +1746,8 @@ describe('Vapor Mode hydration', () => { await nextTick() expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(` "
- -
true
-true- -
" +
true
-true-" `) }) @@ -1922,10 +1912,8 @@ describe('Vapor Mode hydration', () => { expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot( ` "
- abc - -
" + " `, ) @@ -1934,10 +1922,8 @@ describe('Vapor Mode hydration', () => { expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot( ` "
- abc - d -
" + d" `, ) }) @@ -2062,10 +2048,8 @@ describe('Vapor Mode hydration', () => { expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot( ` "
-
comp
comp
comp
- -
" + " `, ) @@ -2074,10 +2058,8 @@ describe('Vapor Mode hydration', () => { expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot( ` "
-
comp
comp
comp
-
comp
-
" +
comp
" `, ) }) @@ -2099,7 +2081,6 @@ describe('Vapor Mode hydration', () => { expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot( ` "
- a @@ -2107,8 +2088,7 @@ describe('Vapor Mode hydration', () => { c - -
" + " `, ) @@ -2117,7 +2097,6 @@ describe('Vapor Mode hydration', () => { expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot( ` "
- a @@ -2125,8 +2104,7 @@ describe('Vapor Mode hydration', () => { c - d -
" + d" `, ) }) @@ -2146,14 +2124,12 @@ describe('Vapor Mode hydration', () => { expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot( ` "
-
foo
-bar-
foo
-bar-
foo
-bar- - -
" + " `, ) @@ -2162,14 +2138,12 @@ describe('Vapor Mode hydration', () => { expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot( ` "
-
foo
-bar-
foo
-bar-
foo
-bar- -
foo
-bar- -
" +
foo
-bar-" `, ) }) @@ -3029,15 +3003,11 @@ describe('Vapor Mode hydration', () => { expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot( ` "
-
-
- +
foo - -
-
+
bar
" `, ) @@ -3048,15 +3018,11 @@ describe('Vapor Mode hydration', () => { expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot( ` "
-
-
- +
foo1 - -
-
+
bar1
" `, ) @@ -3079,10 +3045,8 @@ describe('Vapor Mode hydration', () => { expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot( ` "
- foo - -
" + " `, ) @@ -3091,10 +3055,8 @@ describe('Vapor Mode hydration', () => { expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot( ` "
- foo1 - -
" + " `, ) }) @@ -3378,10 +3340,8 @@ describe('VDOM interop', () => { expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot( ` "
- true - -
" + " `, ) @@ -3390,10 +3350,8 @@ describe('VDOM interop', () => { expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot( ` "
- false - -
" + " `, ) })