Просмотр исходного кода

perf: hoist dynamic props lists

Evan You 5 лет назад
Родитель
Сommit
02339b67d8

+ 5 - 2
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 _Vue = Vue
+const { createElementVNode: _createElementVNode } = _Vue
+
+const _hoisted_1 = [\\"id\\"]
 
 
 return function render(_ctx, _cache) {
 return function render(_ctx, _cache) {
   with (_ctx) {
   with (_ctx) {
     const { createElementVNode: _createElementVNode, openBlock: _openBlock, createElementBlock: _createElementBlock } = _Vue
     const { createElementVNode: _createElementVNode, openBlock: _openBlock, createElementBlock: _createElementBlock } = _Vue
 
 
     return (_openBlock(), _createElementBlock(\\"div\\", null, [
     return (_openBlock(), _createElementBlock(\\"div\\", null, [
-      _createElementVNode(\\"div\\", { id: foo }, null, 8 /* PROPS */, [\\"id\\"])
+      _createElementVNode(\\"div\\", { id: foo }, null, 8 /* PROPS */, _hoisted_1)
     ]))
     ]))
   }
   }
 }"
 }"

+ 7 - 3
packages/compiler-core/__tests__/transforms/hoistStatic.spec.ts

@@ -186,9 +186,9 @@ describe('compiler: hoistStatic transform', () => {
     expect(generate(root).code).toMatchSnapshot()
     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>`)
     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([
     expect((root.codegenNode as VNodeCall).children).toMatchObject([
       {
       {
         type: NodeTypes.ELEMENT,
         type: NodeTypes.ELEMENT,
@@ -200,7 +200,11 @@ describe('compiler: hoistStatic transform', () => {
           }),
           }),
           children: undefined,
           children: undefined,
           patchFlag: genFlagText(PatchFlags.PROPS),
           patchFlag: genFlagText(PatchFlags.PROPS),
-          dynamicProps: `["id"]`
+          dynamicProps: {
+            type: NodeTypes.SIMPLE_EXPRESSION,
+            content: `_hoisted_1`,
+            isStatic: false
+          }
         }
         }
       }
       }
     ])
     ])

+ 1 - 1
packages/compiler-core/src/ast.ts

@@ -288,7 +288,7 @@ export interface VNodeCall extends Node {
     | ForRenderListExpression // v-for fragment call
     | ForRenderListExpression // v-for fragment call
     | undefined
     | undefined
   patchFlag: string | undefined
   patchFlag: string | undefined
-  dynamicProps: string | undefined
+  dynamicProps: string | SimpleExpressionNode | undefined
   directives: DirectiveArguments | undefined
   directives: DirectiveArguments | undefined
   isBlock: boolean
   isBlock: boolean
   disableTracking: boolean
   disableTracking: boolean

+ 2 - 1
packages/compiler-core/src/transform.ts

@@ -113,7 +113,7 @@ export interface TransformContext
   onNodeRemoved(): void
   onNodeRemoved(): void
   addIdentifiers(exp: ExpressionNode | string): void
   addIdentifiers(exp: ExpressionNode | string): void
   removeIdentifiers(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
   cache<T extends JSChildNode>(exp: T, isVNode?: boolean): CacheExpression | T
   constantCache: Map<TemplateChildNode, ConstantTypes>
   constantCache: Map<TemplateChildNode, ConstantTypes>
 
 
@@ -277,6 +277,7 @@ export function createTransformContext(
       }
       }
     },
     },
     hoist(exp) {
     hoist(exp) {
+      if (isString(exp)) exp = createSimpleExpression(exp, false)
       context.hoists.push(exp)
       context.hoists.push(exp)
       const identifier = createSimpleExpression(
       const identifier = createSimpleExpression(
         `_hoisted_${context.hoists.length}`,
         `_hoisted_${context.hoists.length}`,

+ 3 - 0
packages/compiler-core/src/transforms/hoistStatic.ts

@@ -102,6 +102,9 @@ function walk(
               codegenNode.props = context.hoist(props)
               codegenNode.props = context.hoist(props)
             }
             }
           }
           }
+          if (codegenNode.dynamicProps) {
+            codegenNode.dynamicProps = context.hoist(codegenNode.dynamicProps)
+          }
         }
         }
       }
       }
     } else if (child.type === NodeTypes.TEXT_CALL) {
     } else if (child.type === NodeTypes.TEXT_CALL) {