perf: improve VNode creation performance with compiler hints (#3334)

This commit is contained in:
HcySunYang
2021-06-23 07:15:20 +08:00
committed by Evan You
parent 31abdc8ada
commit ceff89905b
42 changed files with 1130 additions and 685 deletions

View File

@@ -9,12 +9,20 @@ import {
ComponentNode,
TemplateNode,
VNodeCall,
ParentNode
ParentNode,
JSChildNode,
CallExpression
} from '../ast'
import { TransformContext } from '../transform'
import { PatchFlags, isString, isSymbol } from '@vue/shared'
import { isSlotOutlet } from '../utils'
import { CREATE_BLOCK, CREATE_VNODE, OPEN_BLOCK } from '../runtimeHelpers'
import { getVNodeBlockHelper, getVNodeHelper, isSlotOutlet } from '../utils'
import {
OPEN_BLOCK,
GUARD_REACTIVE_PROPS,
NORMALIZE_CLASS,
NORMALIZE_PROPS,
NORMALIZE_STYLE
} from '../runtimeHelpers'
export function hoistStatic(root: RootNode, context: TransformContext) {
walk(
@@ -213,9 +221,11 @@ export function getConstantType(
// nested updates.
if (codegenNode.isBlock) {
context.removeHelper(OPEN_BLOCK)
context.removeHelper(CREATE_BLOCK)
context.removeHelper(
getVNodeBlockHelper(context.inSSR, codegenNode.isComponent)
)
codegenNode.isBlock = false
context.helper(CREATE_VNODE)
context.helper(getVNodeHelper(context.inSSR, codegenNode.isComponent))
}
constantCache.set(node, returnType)
@@ -260,6 +270,33 @@ export function getConstantType(
}
}
const allowHoistedHelperSet = new Set([
NORMALIZE_CLASS,
NORMALIZE_STYLE,
NORMALIZE_PROPS,
GUARD_REACTIVE_PROPS
])
function getConstantTypeOfHelperCall(
value: CallExpression,
context: TransformContext
): ConstantTypes {
if (
value.type === NodeTypes.JS_CALL_EXPRESSION &&
!isString(value.callee) &&
allowHoistedHelperSet.has(value.callee)
) {
const arg = value.arguments[0] as JSChildNode
if (arg.type === NodeTypes.SIMPLE_EXPRESSION) {
return getConstantType(arg, context)
} else if (arg.type === NodeTypes.JS_CALL_EXPRESSION) {
// in the case of nested helper call, e.g. `normalizeProps(guardReactiveProps(exp))`
return getConstantTypeOfHelperCall(arg, context)
}
}
return ConstantTypes.NOT_CONSTANT
}
function getGeneratedPropsConstantType(
node: PlainElementNode,
context: TransformContext
@@ -278,6 +315,12 @@ function getGeneratedPropsConstantType(
returnType = keyType
}
if (value.type !== NodeTypes.SIMPLE_EXPRESSION) {
// some helper calls can be hoisted,
// such as the `normalizeProps` generated by the compiler for pre-normalize class,
// in this case we need to respect the ConstanType of the helper's argments
if (value.type === NodeTypes.JS_CALL_EXPRESSION) {
return getConstantTypeOfHelperCall(value, context)
}
return ConstantTypes.NOT_CONSTANT
}
const valueType = getConstantType(value, context)