perf: only trigger $attrs update when it has actually changed

This commit is contained in:
Evan You 2021-04-21 19:05:20 -04:00
parent 66b6b4226b
commit 5566d39d46

View File

@ -188,6 +188,7 @@ export function updateProps(
} = instance } = instance
const rawCurrentProps = toRaw(props) const rawCurrentProps = toRaw(props)
const [options] = instance.propsOptions const [options] = instance.propsOptions
let hasAttrsChanged = false
if ( if (
// always force full diff in dev // always force full diff in dev
@ -213,7 +214,10 @@ export function updateProps(
// attr / props separation was done on init and will be consistent // attr / props separation was done on init and will be consistent
// in this code path, so just check if attrs have it. // in this code path, so just check if attrs have it.
if (hasOwn(attrs, key)) { if (hasOwn(attrs, key)) {
if (value !== attrs[key]) {
attrs[key] = value attrs[key] = value
hasAttrsChanged = true
}
} else { } else {
const camelizedKey = camelize(key) const camelizedKey = camelize(key)
props[camelizedKey] = resolvePropValue( props[camelizedKey] = resolvePropValue(
@ -232,13 +236,18 @@ export function updateProps(
) { ) {
continue continue
} }
if (value !== attrs[key]) {
attrs[key] = value attrs[key] = value
hasAttrsChanged = true
}
} }
} }
} }
} else { } else {
// full props update. // full props update.
setFullProps(instance, rawProps, props, attrs) if (setFullProps(instance, rawProps, props, attrs)) {
hasAttrsChanged = true
}
// in case of dynamic props, check if we need to delete keys from // in case of dynamic props, check if we need to delete keys from
// the props object // the props object
let kebabKey: string let kebabKey: string
@ -278,13 +287,16 @@ export function updateProps(
for (const key in attrs) { for (const key in attrs) {
if (!rawProps || !hasOwn(rawProps, key)) { if (!rawProps || !hasOwn(rawProps, key)) {
delete attrs[key] delete attrs[key]
hasAttrsChanged = true
} }
} }
} }
} }
// trigger updates for $attrs in case it's used in component slots // trigger updates for $attrs in case it's used in component slots
if (hasAttrsChanged) {
trigger(instance, TriggerOpTypes.SET, '$attrs') trigger(instance, TriggerOpTypes.SET, '$attrs')
}
if (__DEV__) { if (__DEV__) {
validateProps(rawProps || {}, props, instance) validateProps(rawProps || {}, props, instance)
@ -298,6 +310,7 @@ function setFullProps(
attrs: Data attrs: Data
) { ) {
const [options, needCastKeys] = instance.propsOptions const [options, needCastKeys] = instance.propsOptions
let hasAttrsChanged = false
if (rawProps) { if (rawProps) {
for (const key in rawProps) { for (const key in rawProps) {
// key, ref are reserved and never passed down // key, ref are reserved and never passed down
@ -335,7 +348,10 @@ function setFullProps(
) { ) {
continue continue
} }
if (value !== attrs[key]) {
attrs[key] = value attrs[key] = value
hasAttrsChanged = true
}
} }
} }
} }
@ -353,6 +369,8 @@ function setFullProps(
) )
} }
} }
return hasAttrsChanged
} }
function resolvePropValue( function resolvePropValue(