perf: improve VNode creation performance with compiler hints (#3334)
This commit is contained in:
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user