Skip to content

Commit 6af733d

Browse files
committed
perf: optimize component props/slots internal object checks
1 parent 4bc9f39 commit 6af733d

File tree

3 files changed

+12
-11
lines changed

3 files changed

+12
-11
lines changed

packages/runtime-core/src/componentProps.ts

+8-4
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import {
1212
PatchFlags,
1313
camelize,
1414
capitalize,
15-
def,
1615
extend,
1716
hasOwn,
1817
hyphenate,
@@ -34,7 +33,6 @@ import {
3433
setCurrentInstance,
3534
} from './component'
3635
import { isEmitListener } from './componentEmits'
37-
import { InternalObjectKey } from './vnode'
3836
import type { AppContext } from './apiCreateApp'
3937
import { createPropsDefaultThis } from './compat/props'
4038
import { isCompatEnabled, softAssertCompatEnabled } from './compat/compatConfig'
@@ -187,15 +185,21 @@ type NormalizedProp =
187185
export type NormalizedProps = Record<string, NormalizedProp>
188186
export type NormalizedPropsOptions = [NormalizedProps, string[]] | []
189187

188+
/**
189+
* Used during vnode props normalization to check if the vnode props is the
190+
* attrs object of a component via `Object.getPrototypeOf`. This is more
191+
* performant than defining a non-enumerable property.
192+
*/
193+
export const attrsProto = {}
194+
190195
export function initProps(
191196
instance: ComponentInternalInstance,
192197
rawProps: Data | null,
193198
isStateful: number, // result of bitwise flag comparison
194199
isSSR = false,
195200
) {
196201
const props: Data = {}
197-
const attrs: Data = {}
198-
def(attrs, InternalObjectKey, 1)
202+
const attrs: Data = Object.create(attrsProto)
199203

200204
instance.propsDefaults = Object.create(null)
201205

packages/runtime-core/src/componentSlots.ts

+1-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { type ComponentInternalInstance, currentInstance } from './component'
22
import {
3-
InternalObjectKey,
43
type VNode,
54
type VNodeChild,
65
type VNodeNormalizedChildren,
@@ -174,7 +173,7 @@ export const initSlots = (
174173
// we should avoid the proxy object polluting the slots of the internal instance
175174
instance.slots = toRaw(children as InternalSlots)
176175
// make compiler marker non-enumerable
177-
def(children as InternalSlots, '_', type)
176+
def(instance.slots, '_', type)
178177
} else {
179178
normalizeObjectSlots(
180179
children as RawSlots,
@@ -188,7 +187,6 @@ export const initSlots = (
188187
normalizeVNodeSlots(instance, children)
189188
}
190189
}
191-
def(instance.slots, InternalObjectKey, 1)
192190
}
193191

194192
export const updateSlots = (

packages/runtime-core/src/vnode.ts

+3-4
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ import { convertLegacyVModelProps } from './compat/componentVModel'
5555
import { defineLegacyVNodeProperties } from './compat/renderFn'
5656
import { ErrorCodes, callWithAsyncErrorHandling } from './errorHandling'
5757
import type { ComponentPublicInstance } from './componentPublicInstance'
58+
import { attrsProto } from './componentProps'
5859

5960
export const Fragment = Symbol.for('v-fgt') as any as {
6061
__isFragment: true
@@ -404,8 +405,6 @@ const createVNodeWithArgsTransform = (
404405
)
405406
}
406407

407-
export const InternalObjectKey = `__vInternal`
408-
409408
const normalizeKey = ({ key }: VNodeProps): VNode['key'] =>
410409
key != null ? key : null
411410

@@ -618,7 +617,7 @@ function _createVNode(
618617

619618
export function guardReactiveProps(props: (Data & VNodeProps) | null) {
620619
if (!props) return null
621-
return isProxy(props) || InternalObjectKey in props
620+
return isProxy(props) || Object.getPrototypeOf(props) === attrsProto
622621
? extend({}, props)
623622
: props
624623
}
@@ -792,7 +791,7 @@ export function normalizeChildren(vnode: VNode, children: unknown) {
792791
} else {
793792
type = ShapeFlags.SLOTS_CHILDREN
794793
const slotFlag = (children as RawSlots)._
795-
if (!slotFlag && !(InternalObjectKey in children!)) {
794+
if (!slotFlag) {
796795
// if slots are not normalized, attach context instance
797796
// (compiled / normalized slots already have context)
798797
;(children as RawSlots)._ctx = currentRenderingInstance

0 commit comments

Comments
 (0)