Skip to content

Commit 02339b6

Browse files
committed
perf: hoist dynamic props lists
1 parent 979a841 commit 02339b6

File tree

5 files changed

+18
-7
lines changed

5 files changed

+18
-7
lines changed

packages/compiler-core/__tests__/transforms/__snapshots__/hoistStatic.spec.ts.snap

+5-2
Original file line numberDiff line numberDiff line change
@@ -319,15 +319,18 @@ return function render(_ctx, _cache) {
319319
}"
320320
`;
321321
322-
exports[`compiler: hoistStatic transform should NOT hoist element with dynamic props 1`] = `
322+
exports[`compiler: hoistStatic transform should NOT hoist element with dynamic props (but hoist the props list) 1`] = `
323323
"const _Vue = Vue
324+
const { createElementVNode: _createElementVNode } = _Vue
325+
326+
const _hoisted_1 = [\\"id\\"]
324327
325328
return function render(_ctx, _cache) {
326329
with (_ctx) {
327330
const { createElementVNode: _createElementVNode, openBlock: _openBlock, createElementBlock: _createElementBlock } = _Vue
328331
329332
return (_openBlock(), _createElementBlock(\\"div\\", null, [
330-
_createElementVNode(\\"div\\", { id: foo }, null, 8 /* PROPS */, [\\"id\\"])
333+
_createElementVNode(\\"div\\", { id: foo }, null, 8 /* PROPS */, _hoisted_1)
331334
]))
332335
}
333336
}"

packages/compiler-core/__tests__/transforms/hoistStatic.spec.ts

+7-3
Original file line numberDiff line numberDiff line change
@@ -186,9 +186,9 @@ describe('compiler: hoistStatic transform', () => {
186186
expect(generate(root).code).toMatchSnapshot()
187187
})
188188

189-
test('should NOT hoist element with dynamic props', () => {
189+
test('should NOT hoist element with dynamic props (but hoist the props list)', () => {
190190
const root = transformWithHoist(`<div><div :id="foo"/></div>`)
191-
expect(root.hoists.length).toBe(0)
191+
expect(root.hoists.length).toBe(1)
192192
expect((root.codegenNode as VNodeCall).children).toMatchObject([
193193
{
194194
type: NodeTypes.ELEMENT,
@@ -200,7 +200,11 @@ describe('compiler: hoistStatic transform', () => {
200200
}),
201201
children: undefined,
202202
patchFlag: genFlagText(PatchFlags.PROPS),
203-
dynamicProps: `["id"]`
203+
dynamicProps: {
204+
type: NodeTypes.SIMPLE_EXPRESSION,
205+
content: `_hoisted_1`,
206+
isStatic: false
207+
}
204208
}
205209
}
206210
])

packages/compiler-core/src/ast.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ export interface VNodeCall extends Node {
288288
| ForRenderListExpression // v-for fragment call
289289
| undefined
290290
patchFlag: string | undefined
291-
dynamicProps: string | undefined
291+
dynamicProps: string | SimpleExpressionNode | undefined
292292
directives: DirectiveArguments | undefined
293293
isBlock: boolean
294294
disableTracking: boolean

packages/compiler-core/src/transform.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ export interface TransformContext
113113
onNodeRemoved(): void
114114
addIdentifiers(exp: ExpressionNode | string): void
115115
removeIdentifiers(exp: ExpressionNode | string): void
116-
hoist(exp: JSChildNode): SimpleExpressionNode
116+
hoist(exp: string | JSChildNode): SimpleExpressionNode
117117
cache<T extends JSChildNode>(exp: T, isVNode?: boolean): CacheExpression | T
118118
constantCache: Map<TemplateChildNode, ConstantTypes>
119119

@@ -277,6 +277,7 @@ export function createTransformContext(
277277
}
278278
},
279279
hoist(exp) {
280+
if (isString(exp)) exp = createSimpleExpression(exp, false)
280281
context.hoists.push(exp)
281282
const identifier = createSimpleExpression(
282283
`_hoisted_${context.hoists.length}`,

packages/compiler-core/src/transforms/hoistStatic.ts

+3
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,9 @@ function walk(
102102
codegenNode.props = context.hoist(props)
103103
}
104104
}
105+
if (codegenNode.dynamicProps) {
106+
codegenNode.dynamicProps = context.hoist(codegenNode.dynamicProps)
107+
}
105108
}
106109
}
107110
} else if (child.type === NodeTypes.TEXT_CALL) {

0 commit comments

Comments
 (0)