fix(compiler-dom): fix stringify static edge for partially eligible chunks in cached parent

close #11879
close #11890
This commit is contained in:
Evan You 2024-09-13 20:08:24 +08:00
parent 7571f20bc3
commit 1d99d61c1b
No known key found for this signature in database
GPG Key ID: 00E9AB7A6704CE0A
3 changed files with 38 additions and 6 deletions

View File

@ -1,5 +1,17 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`stringify static html > eligible content (elements > 20) + non-eligible content 1`] = `
"const { createElementVNode: _createElementVNode, createStaticVNode: _createStaticVNode, openBlock: _openBlock, createElementBlock: _createElementBlock } = Vue
return function render(_ctx, _cache) {
return (_openBlock(), _createElementBlock("div", null, _cache[0] || (_cache[0] = [
_createStaticVNode("<span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span>", 20),
_createElementVNode("div", { key: "1" }, "1", -1 /* HOISTED */),
_createStaticVNode("<span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span>", 20)
])))
}"
`;
exports[`stringify static html > escape 1`] = ` exports[`stringify static html > escape 1`] = `
"const { toDisplayString: _toDisplayString, normalizeClass: _normalizeClass, createElementVNode: _createElementVNode, createStaticVNode: _createStaticVNode, openBlock: _openBlock, createElementBlock: _createElementBlock } = Vue "const { toDisplayString: _toDisplayString, normalizeClass: _normalizeClass, createElementVNode: _createElementVNode, createStaticVNode: _createStaticVNode, openBlock: _openBlock, createElementBlock: _createElementBlock } = Vue

View File

@ -451,4 +451,18 @@ describe('stringify static html', () => {
expect(ast.cached).toMatchObject([cachedArrayBailedMatcher()]) expect(ast.cached).toMatchObject([cachedArrayBailedMatcher()])
expect(code).toMatchSnapshot() expect(code).toMatchSnapshot()
}) })
test('eligible content (elements > 20) + non-eligible content', () => {
const { code } = compileWithStringify(
`<div>${repeat(
`<span/>`,
StringifyThresholds.NODE_COUNT,
)}<div key="1">1</div>${repeat(
`<span/>`,
StringifyThresholds.NODE_COUNT,
)}</div>`,
)
expect(code).toMatchSnapshot()
})
}) })

View File

@ -16,8 +16,6 @@ import {
type TemplateChildNode, type TemplateChildNode,
type TextCallNode, type TextCallNode,
type TransformContext, type TransformContext,
type VNodeCall,
createArrayExpression,
createCallExpression, createCallExpression,
isStaticArgOf, isStaticArgOf,
} from '@vue/compiler-core' } from '@vue/compiler-core'
@ -106,15 +104,23 @@ export const stringifyStatic: HoistTransform = (children, context, parent) => {
String(currentChunk.length), String(currentChunk.length),
]) ])
const deleteCount = currentChunk.length - 1
if (isParentCached) { if (isParentCached) {
;((parent.codegenNode as VNodeCall).children as CacheExpression).value = // if the parent is cached, then `children` is also the value of the
createArrayExpression([staticCall]) // CacheExpression. Just replace the corresponding range in the cached
// list with staticCall.
children.splice(
currentIndex - currentChunk.length,
currentChunk.length,
// @ts-expect-error
staticCall,
)
} else { } else {
// replace the first node's hoisted expression with the static vnode call // replace the first node's hoisted expression with the static vnode call
;(currentChunk[0].codegenNode as CacheExpression).value = staticCall ;(currentChunk[0].codegenNode as CacheExpression).value = staticCall
if (currentChunk.length > 1) { if (currentChunk.length > 1) {
// remove merged nodes from children // remove merged nodes from children
const deleteCount = currentChunk.length - 1
children.splice(currentIndex - currentChunk.length + 1, deleteCount) children.splice(currentIndex - currentChunk.length + 1, deleteCount)
// also adjust index for the remaining cache items // also adjust index for the remaining cache items
const cacheIndex = context.cached.indexOf( const cacheIndex = context.cached.indexOf(
@ -128,9 +134,9 @@ export const stringifyStatic: HoistTransform = (children, context, parent) => {
} }
context.cached.splice(cacheIndex - deleteCount + 1, deleteCount) context.cached.splice(cacheIndex - deleteCount + 1, deleteCount)
} }
return deleteCount
} }
} }
return deleteCount
} }
return 0 return 0
} }