mirror of https://github.com/vuejs/core.git
perf: optimize component props/slots internal object checks
This commit is contained in:
parent
4bc9f39f02
commit
6af733d68e
|
@ -12,7 +12,6 @@ import {
|
||||||
PatchFlags,
|
PatchFlags,
|
||||||
camelize,
|
camelize,
|
||||||
capitalize,
|
capitalize,
|
||||||
def,
|
|
||||||
extend,
|
extend,
|
||||||
hasOwn,
|
hasOwn,
|
||||||
hyphenate,
|
hyphenate,
|
||||||
|
@ -34,7 +33,6 @@ import {
|
||||||
setCurrentInstance,
|
setCurrentInstance,
|
||||||
} from './component'
|
} from './component'
|
||||||
import { isEmitListener } from './componentEmits'
|
import { isEmitListener } from './componentEmits'
|
||||||
import { InternalObjectKey } from './vnode'
|
|
||||||
import type { AppContext } from './apiCreateApp'
|
import type { AppContext } from './apiCreateApp'
|
||||||
import { createPropsDefaultThis } from './compat/props'
|
import { createPropsDefaultThis } from './compat/props'
|
||||||
import { isCompatEnabled, softAssertCompatEnabled } from './compat/compatConfig'
|
import { isCompatEnabled, softAssertCompatEnabled } from './compat/compatConfig'
|
||||||
|
@ -187,6 +185,13 @@ type NormalizedProp =
|
||||||
export type NormalizedProps = Record<string, NormalizedProp>
|
export type NormalizedProps = Record<string, NormalizedProp>
|
||||||
export type NormalizedPropsOptions = [NormalizedProps, string[]] | []
|
export type NormalizedPropsOptions = [NormalizedProps, string[]] | []
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used during vnode props normalization to check if the vnode props is the
|
||||||
|
* attrs object of a component via `Object.getPrototypeOf`. This is more
|
||||||
|
* performant than defining a non-enumerable property.
|
||||||
|
*/
|
||||||
|
export const attrsProto = {}
|
||||||
|
|
||||||
export function initProps(
|
export function initProps(
|
||||||
instance: ComponentInternalInstance,
|
instance: ComponentInternalInstance,
|
||||||
rawProps: Data | null,
|
rawProps: Data | null,
|
||||||
|
@ -194,8 +199,7 @@ export function initProps(
|
||||||
isSSR = false,
|
isSSR = false,
|
||||||
) {
|
) {
|
||||||
const props: Data = {}
|
const props: Data = {}
|
||||||
const attrs: Data = {}
|
const attrs: Data = Object.create(attrsProto)
|
||||||
def(attrs, InternalObjectKey, 1)
|
|
||||||
|
|
||||||
instance.propsDefaults = Object.create(null)
|
instance.propsDefaults = Object.create(null)
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import { type ComponentInternalInstance, currentInstance } from './component'
|
import { type ComponentInternalInstance, currentInstance } from './component'
|
||||||
import {
|
import {
|
||||||
InternalObjectKey,
|
|
||||||
type VNode,
|
type VNode,
|
||||||
type VNodeChild,
|
type VNodeChild,
|
||||||
type VNodeNormalizedChildren,
|
type VNodeNormalizedChildren,
|
||||||
|
@ -174,7 +173,7 @@ export const initSlots = (
|
||||||
// we should avoid the proxy object polluting the slots of the internal instance
|
// we should avoid the proxy object polluting the slots of the internal instance
|
||||||
instance.slots = toRaw(children as InternalSlots)
|
instance.slots = toRaw(children as InternalSlots)
|
||||||
// make compiler marker non-enumerable
|
// make compiler marker non-enumerable
|
||||||
def(children as InternalSlots, '_', type)
|
def(instance.slots, '_', type)
|
||||||
} else {
|
} else {
|
||||||
normalizeObjectSlots(
|
normalizeObjectSlots(
|
||||||
children as RawSlots,
|
children as RawSlots,
|
||||||
|
@ -188,7 +187,6 @@ export const initSlots = (
|
||||||
normalizeVNodeSlots(instance, children)
|
normalizeVNodeSlots(instance, children)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
def(instance.slots, InternalObjectKey, 1)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const updateSlots = (
|
export const updateSlots = (
|
||||||
|
|
|
@ -55,6 +55,7 @@ import { convertLegacyVModelProps } from './compat/componentVModel'
|
||||||
import { defineLegacyVNodeProperties } from './compat/renderFn'
|
import { defineLegacyVNodeProperties } from './compat/renderFn'
|
||||||
import { ErrorCodes, callWithAsyncErrorHandling } from './errorHandling'
|
import { ErrorCodes, callWithAsyncErrorHandling } from './errorHandling'
|
||||||
import type { ComponentPublicInstance } from './componentPublicInstance'
|
import type { ComponentPublicInstance } from './componentPublicInstance'
|
||||||
|
import { attrsProto } from './componentProps'
|
||||||
|
|
||||||
export const Fragment = Symbol.for('v-fgt') as any as {
|
export const Fragment = Symbol.for('v-fgt') as any as {
|
||||||
__isFragment: true
|
__isFragment: true
|
||||||
|
@ -404,8 +405,6 @@ const createVNodeWithArgsTransform = (
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const InternalObjectKey = `__vInternal`
|
|
||||||
|
|
||||||
const normalizeKey = ({ key }: VNodeProps): VNode['key'] =>
|
const normalizeKey = ({ key }: VNodeProps): VNode['key'] =>
|
||||||
key != null ? key : null
|
key != null ? key : null
|
||||||
|
|
||||||
|
@ -618,7 +617,7 @@ function _createVNode(
|
||||||
|
|
||||||
export function guardReactiveProps(props: (Data & VNodeProps) | null) {
|
export function guardReactiveProps(props: (Data & VNodeProps) | null) {
|
||||||
if (!props) return null
|
if (!props) return null
|
||||||
return isProxy(props) || InternalObjectKey in props
|
return isProxy(props) || Object.getPrototypeOf(props) === attrsProto
|
||||||
? extend({}, props)
|
? extend({}, props)
|
||||||
: props
|
: props
|
||||||
}
|
}
|
||||||
|
@ -792,7 +791,7 @@ export function normalizeChildren(vnode: VNode, children: unknown) {
|
||||||
} else {
|
} else {
|
||||||
type = ShapeFlags.SLOTS_CHILDREN
|
type = ShapeFlags.SLOTS_CHILDREN
|
||||||
const slotFlag = (children as RawSlots)._
|
const slotFlag = (children as RawSlots)._
|
||||||
if (!slotFlag && !(InternalObjectKey in children!)) {
|
if (!slotFlag) {
|
||||||
// if slots are not normalized, attach context instance
|
// if slots are not normalized, attach context instance
|
||||||
// (compiled / normalized slots already have context)
|
// (compiled / normalized slots already have context)
|
||||||
;(children as RawSlots)._ctx = currentRenderingInstance
|
;(children as RawSlots)._ctx = currentRenderingInstance
|
||||||
|
|
Loading…
Reference in New Issue