Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 371edbe

Browse filesBrowse files
committed
fix(compiler-core): remove slot cache from parent renderCache during unmounting
1 parent 4f79253 commit 371edbe
Copy full SHA for 371edbe

File tree

Expand file treeCollapse file tree

5 files changed

+61
-3
lines changed
Filter options
Expand file treeCollapse file tree

5 files changed

+61
-3
lines changed

‎packages/compiler-core/__tests__/transforms/cacheStatic.spec.ts

Copy file name to clipboardExpand all lines: packages/compiler-core/__tests__/transforms/cacheStatic.spec.ts
+10Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,11 @@ describe('compiler: cacheStatic transform', () => {
170170
{
171171
/* _ slot flag */
172172
},
173+
{
174+
type: NodeTypes.JS_PROPERTY,
175+
key: { content: '__' },
176+
value: { content: '[0]' },
177+
},
173178
],
174179
})
175180
})
@@ -197,6 +202,11 @@ describe('compiler: cacheStatic transform', () => {
197202
{
198203
/* _ slot flag */
199204
},
205+
{
206+
type: NodeTypes.JS_PROPERTY,
207+
key: { content: '__' },
208+
value: { content: '[0]' },
209+
},
200210
],
201211
})
202212
})

‎packages/compiler-core/src/transforms/cacheStatic.ts

Copy file name to clipboardExpand all lines: packages/compiler-core/src/transforms/cacheStatic.ts
+27Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,14 @@ import {
1212
type RootNode,
1313
type SimpleExpressionNode,
1414
type SlotFunctionExpression,
15+
type SlotsObjectProperty,
1516
type TemplateChildNode,
1617
type TemplateNode,
1718
type TextCallNode,
1819
type VNodeCall,
1920
createArrayExpression,
21+
createObjectProperty,
22+
createSimpleExpression,
2023
getVNodeBlockHelper,
2124
getVNodeHelper,
2225
} from '../ast'
@@ -140,6 +143,7 @@ function walk(
140143
}
141144

142145
let cachedAsArray = false
146+
const slotCacheKeys = []
143147
if (toCache.length === children.length && node.type === NodeTypes.ELEMENT) {
144148
if (
145149
node.tagType === ElementTypes.ELEMENT &&
@@ -163,6 +167,7 @@ function walk(
163167
// default slot
164168
const slot = getSlotNode(node.codegenNode, 'default')
165169
if (slot) {
170+
slotCacheKeys.push(context.cached.length)
166171
slot.returns = getCacheExpression(
167172
createArrayExpression(slot.returns as TemplateChildNode[]),
168173
)
@@ -186,6 +191,7 @@ function walk(
186191
slotName.arg &&
187192
getSlotNode(parent.codegenNode, slotName.arg)
188193
if (slot) {
194+
slotCacheKeys.push(context.cached.length)
189195
slot.returns = getCacheExpression(
190196
createArrayExpression(slot.returns as TemplateChildNode[]),
191197
)
@@ -196,10 +202,31 @@ function walk(
196202

197203
if (!cachedAsArray) {
198204
for (const child of toCache) {
205+
slotCacheKeys.push(context.cached.length)
199206
child.codegenNode = context.cache(child.codegenNode!)
200207
}
201208
}
202209

210+
// put the slot cached keys on the slot object, so that the cache
211+
// can be removed when component unmounting to prevent memory leaks
212+
if (
213+
slotCacheKeys.length &&
214+
node.type === NodeTypes.ELEMENT &&
215+
node.tagType === ElementTypes.COMPONENT &&
216+
node.codegenNode &&
217+
node.codegenNode.type === NodeTypes.VNODE_CALL &&
218+
node.codegenNode.children &&
219+
!isArray(node.codegenNode.children) &&
220+
node.codegenNode.children.type === NodeTypes.JS_OBJECT_EXPRESSION
221+
) {
222+
node.codegenNode.children.properties.push(
223+
createObjectProperty(
224+
`__`,
225+
createSimpleExpression(JSON.stringify(slotCacheKeys), false),
226+
) as SlotsObjectProperty,
227+
)
228+
}
229+
203230
function getCacheExpression(value: JSChildNode): CacheExpression {
204231
const exp = context.cache(value)
205232
// #6978, #7138, #7114

‎packages/compiler-core/src/transforms/vSlot.ts

Copy file name to clipboardExpand all lines: packages/compiler-core/src/transforms/vSlot.ts
-1Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -342,7 +342,6 @@ export function buildSlots(
342342
: hasForwardedSlots(node.children)
343343
? SlotFlags.FORWARDED
344344
: SlotFlags.STABLE
345-
346345
let slots = createObjectExpression(
347346
slotsProperties.concat(
348347
createObjectProperty(

‎packages/runtime-core/src/componentSlots.ts

Copy file name to clipboardExpand all lines: packages/runtime-core/src/componentSlots.ts
+6-1Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,11 @@ export type RawSlots = {
7575
* @internal
7676
*/
7777
_?: SlotFlags
78+
/**
79+
* cache indexes for slot content
80+
* @internal
81+
*/
82+
__?: number[]
7883
}
7984

8085
const isInternalKey = (key: string) => key[0] === '_' || key === '$stable'
@@ -170,7 +175,7 @@ const assignSlots = (
170175
// when rendering the optimized slots by manually written render function,
171176
// do not copy the `slots._` compiler flag so that `renderSlot` creates
172177
// slot Fragment with BAIL patchFlag to force full updates
173-
if (optimized || key !== '_') {
178+
if (optimized || !key.startsWith('_')) {
174179
slots[key] = children[key]
175180
}
176181
}

‎packages/runtime-core/src/renderer.ts

Copy file name to clipboardExpand all lines: packages/runtime-core/src/renderer.ts
+18-1Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2262,7 +2262,17 @@ function baseCreateRenderer(
22622262
unregisterHMR(instance)
22632263
}
22642264

2265-
const { bum, scope, job, subTree, um, m, a } = instance
2265+
const {
2266+
bum,
2267+
scope,
2268+
job,
2269+
subTree,
2270+
um,
2271+
m,
2272+
a,
2273+
parent,
2274+
slots: { __: slotCacheKeys },
2275+
} = instance
22662276
invalidateMount(m)
22672277
invalidateMount(a)
22682278

@@ -2271,6 +2281,13 @@ function baseCreateRenderer(
22712281
invokeArrayFns(bum)
22722282
}
22732283

2284+
// remove slots content from parent renderCache
2285+
if (parent && isArray(slotCacheKeys)) {
2286+
slotCacheKeys.forEach(v => {
2287+
parent.renderCache[v] = undefined
2288+
})
2289+
}
2290+
22742291
if (
22752292
__COMPAT__ &&
22762293
isCompatEnabled(DeprecationTypes.INSTANCE_EVENT_HOOKS, instance)

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.