]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
perf: hoist dynamic props lists
authorEvan You <yyx990803@gmail.com>
Wed, 7 Jul 2021 18:47:59 +0000 (14:47 -0400)
committerEvan You <yyx990803@gmail.com>
Fri, 16 Jul 2021 18:30:49 +0000 (14:30 -0400)
packages/compiler-core/__tests__/transforms/__snapshots__/hoistStatic.spec.ts.snap
packages/compiler-core/__tests__/transforms/hoistStatic.spec.ts
packages/compiler-core/src/ast.ts
packages/compiler-core/src/transform.ts
packages/compiler-core/src/transforms/hoistStatic.ts

index 430aa254e52044e530452e1657798a75d7e9b040..32a6fd611ee0a6a04811ca73b64542c4c958eccb 100644 (file)
@@ -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)
     ]))
   }
 }"
index a91635ed6874f53c14b35c261c2ad98a305d4838..b2e125afdf5c4e1eb54930362f8ff620bc4bf0ae 100644 (file)
@@ -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(`<div><div :id="foo"/></div>`)
-    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
+          }
         }
       }
     ])
index b5f933ea59a18355bd2e865141373dac8ab4131a..2cec62d732d85eb2e8e55d24b404493d8fc20215 100644 (file)
@@ -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
index e2329b039b192e87a0aa5a153ff91bde45441426..bc03d35135f4954fd0da7008edf7b4dcffd6b911 100644 (file)
@@ -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<T extends JSChildNode>(exp: T, isVNode?: boolean): CacheExpression | T
   constantCache: Map<TemplateChildNode, ConstantTypes>
 
@@ -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}`,
index aad6d8794130f65d7df8b8839833a71d4b990d6f..ee18b550fc821edd29913e4f5efdc02d554e8bb6 100644 (file)
@@ -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) {