Skip to content

Commit 528705f

Browse files
committed
perf(vapor): v-for remove all fast path
1 parent bd5c158 commit 528705f

File tree

4 files changed

+35
-6
lines changed

4 files changed

+35
-6
lines changed

packages/compiler-vapor/src/generators/for.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,18 @@ export function genFor(
1616
context: CodegenContext,
1717
): CodeFragment[] {
1818
const { helper } = context
19-
const { source, value, key, index, render, keyProp, once, id, component } =
20-
oper
19+
const {
20+
source,
21+
value,
22+
key,
23+
index,
24+
render,
25+
keyProp,
26+
once,
27+
id,
28+
component,
29+
onlyChild,
30+
} = oper
2131

2232
let rawValue: string | null = null
2333
const rawKey = key && key.content
@@ -80,6 +90,7 @@ export function genFor(
8090
genCallback(keyProp),
8191
component && 'true',
8292
once && 'true',
93+
onlyChild && `true`,
8394
// todo: hydrationNode
8495
),
8596
]

packages/compiler-vapor/src/ir/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ export interface ForIRNode extends BaseIRNode, IRFor {
8989
render: BlockIRNode
9090
once: boolean
9191
component: boolean
92+
onlyChild: boolean
9293
}
9394

9495
export interface SetPropIRNode extends BaseIRNode {

packages/compiler-vapor/src/transforms/vFor.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,16 @@ export function processFor(
5757

5858
return (): void => {
5959
exitBlock()
60+
61+
const { parent } = context
62+
63+
// if v-for is the only child of a parent element, it can go the fast path
64+
// when the entire list is emptied
65+
const isOnlyChild =
66+
parent &&
67+
parent.block.node !== parent.node &&
68+
parent.node.children.length === 1
69+
6070
context.registerOperation({
6171
type: IRNodeTypes.FOR,
6272
id,
@@ -68,6 +78,7 @@ export function processFor(
6878
render,
6979
once: context.inVOnce,
7080
component: isComponent,
81+
onlyChild: !!isOnlyChild,
7182
})
7283
}
7384
}

packages/runtime-vapor/src/apiCreateFor.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ export const createFor = (
7070
*/
7171
isComponent = false,
7272
once?: boolean,
73+
canUseFastRemove?: boolean,
7374
// hydrationNode?: Node,
7475
): VaporFragment => {
7576
let isMounted = false
@@ -105,9 +106,14 @@ export const createFor = (
105106
mount(source, i)
106107
}
107108
} else if (!newLength) {
108-
// fast path for clearing
109+
// fast path for clearing all
110+
const doRemove = !canUseFastRemove
109111
for (let i = 0; i < oldLength; i++) {
110-
unmount(oldBlocks[i])
112+
unmount(oldBlocks[i], doRemove)
113+
}
114+
if (canUseFastRemove) {
115+
parent!.textContent = ''
116+
parent!.appendChild(parentAnchor)
111117
}
112118
} else if (!getKey) {
113119
// unkeyed fast path
@@ -343,9 +349,9 @@ export const createFor = (
343349
}
344350
}
345351

346-
const unmount = ({ nodes, scope }: ForBlock) => {
352+
const unmount = ({ nodes, scope }: ForBlock, doRemove = true) => {
347353
scope && scope.stop()
348-
removeBlock(nodes, parent!)
354+
doRemove && removeBlock(nodes, parent!)
349355
}
350356

351357
once ? renderList() : renderEffect(renderList)

0 commit comments

Comments
 (0)