From 02339b67d8c6fab6ee701a7c4f2773139ed007f5 Mon Sep 17 00:00:00 2001 From: Evan You Date: Wed, 7 Jul 2021 14:47:59 -0400 Subject: [PATCH] perf: hoist dynamic props lists --- .../transforms/__snapshots__/hoistStatic.spec.ts.snap | 7 +++++-- .../__tests__/transforms/hoistStatic.spec.ts | 10 +++++++--- packages/compiler-core/src/ast.ts | 2 +- packages/compiler-core/src/transform.ts | 3 ++- packages/compiler-core/src/transforms/hoistStatic.ts | 3 +++ 5 files changed, 18 insertions(+), 7 deletions(-) diff --git a/packages/compiler-core/__tests__/transforms/__snapshots__/hoistStatic.spec.ts.snap b/packages/compiler-core/__tests__/transforms/__snapshots__/hoistStatic.spec.ts.snap index 430aa254e52..32a6fd611ee 100644 --- a/packages/compiler-core/__tests__/transforms/__snapshots__/hoistStatic.spec.ts.snap +++ b/packages/compiler-core/__tests__/transforms/__snapshots__/hoistStatic.spec.ts.snap @@ -319,15 +319,18 @@ return function render(_ctx, _cache) { }" `; -exports[`compiler: hoistStatic transform should NOT hoist element with dynamic props 1`] = ` +exports[`compiler: hoistStatic transform should NOT hoist element with dynamic props (but hoist the props list) 1`] = ` "const _Vue = Vue +const { createElementVNode: _createElementVNode } = _Vue + +const _hoisted_1 = [\\"id\\"] return function render(_ctx, _cache) { with (_ctx) { const { createElementVNode: _createElementVNode, openBlock: _openBlock, createElementBlock: _createElementBlock } = _Vue return (_openBlock(), _createElementBlock(\\"div\\", null, [ - _createElementVNode(\\"div\\", { id: foo }, null, 8 /* PROPS */, [\\"id\\"]) + _createElementVNode(\\"div\\", { id: foo }, null, 8 /* PROPS */, _hoisted_1) ])) } }" diff --git a/packages/compiler-core/__tests__/transforms/hoistStatic.spec.ts b/packages/compiler-core/__tests__/transforms/hoistStatic.spec.ts index a91635ed687..b2e125afdf5 100644 --- a/packages/compiler-core/__tests__/transforms/hoistStatic.spec.ts +++ b/packages/compiler-core/__tests__/transforms/hoistStatic.spec.ts @@ -186,9 +186,9 @@ describe('compiler: hoistStatic transform', () => { expect(generate(root).code).toMatchSnapshot() }) - test('should NOT hoist element with dynamic props', () => { + test('should NOT hoist element with dynamic props (but hoist the props list)', () => { const root = transformWithHoist(`
`) - expect(root.hoists.length).toBe(0) + expect(root.hoists.length).toBe(1) expect((root.codegenNode as VNodeCall).children).toMatchObject([ { type: NodeTypes.ELEMENT, @@ -200,7 +200,11 @@ describe('compiler: hoistStatic transform', () => { }), children: undefined, patchFlag: genFlagText(PatchFlags.PROPS), - dynamicProps: `["id"]` + dynamicProps: { + type: NodeTypes.SIMPLE_EXPRESSION, + content: `_hoisted_1`, + isStatic: false + } } } ]) diff --git a/packages/compiler-core/src/ast.ts b/packages/compiler-core/src/ast.ts index b5f933ea59a..2cec62d732d 100644 --- a/packages/compiler-core/src/ast.ts +++ b/packages/compiler-core/src/ast.ts @@ -288,7 +288,7 @@ export interface VNodeCall extends Node { | ForRenderListExpression // v-for fragment call | undefined patchFlag: string | undefined - dynamicProps: string | undefined + dynamicProps: string | SimpleExpressionNode | undefined directives: DirectiveArguments | undefined isBlock: boolean disableTracking: boolean diff --git a/packages/compiler-core/src/transform.ts b/packages/compiler-core/src/transform.ts index e2329b039b1..bc03d35135f 100644 --- a/packages/compiler-core/src/transform.ts +++ b/packages/compiler-core/src/transform.ts @@ -113,7 +113,7 @@ export interface TransformContext onNodeRemoved(): void addIdentifiers(exp: ExpressionNode | string): void removeIdentifiers(exp: ExpressionNode | string): void - hoist(exp: JSChildNode): SimpleExpressionNode + hoist(exp: string | JSChildNode): SimpleExpressionNode cache(exp: T, isVNode?: boolean): CacheExpression | T constantCache: Map @@ -277,6 +277,7 @@ export function createTransformContext( } }, hoist(exp) { + if (isString(exp)) exp = createSimpleExpression(exp, false) context.hoists.push(exp) const identifier = createSimpleExpression( `_hoisted_${context.hoists.length}`, diff --git a/packages/compiler-core/src/transforms/hoistStatic.ts b/packages/compiler-core/src/transforms/hoistStatic.ts index aad6d879413..ee18b550fc8 100644 --- a/packages/compiler-core/src/transforms/hoistStatic.ts +++ b/packages/compiler-core/src/transforms/hoistStatic.ts @@ -102,6 +102,9 @@ function walk( codegenNode.props = context.hoist(props) } } + if (codegenNode.dynamicProps) { + codegenNode.dynamicProps = context.hoist(codegenNode.dynamicProps) + } } } } else if (child.type === NodeTypes.TEXT_CALL) {