From: Evan You Date: Wed, 2 Jun 2021 19:22:52 +0000 (-0400) Subject: perf: avoid deopt for props/emits normalization when global mixins are used X-Git-Tag: v3.1.0-beta.7~3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=51d2be20386d4dc59006d31a1cc96676871027ce;p=thirdparty%2Fvuejs%2Fcore.git perf: avoid deopt for props/emits normalization when global mixins are used --- diff --git a/packages/runtime-core/src/apiCreateApp.ts b/packages/runtime-core/src/apiCreateApp.ts index 617ddd20e3..4bdc21c1da 100644 --- a/packages/runtime-core/src/apiCreateApp.ts +++ b/packages/runtime-core/src/apiCreateApp.ts @@ -20,6 +20,8 @@ import { devtoolsInitApp, devtoolsUnmountApp } from './devtools' import { isFunction, NO, isObject } from '@vue/shared' import { version } from '.' import { installAppCompatProperties } from './compat/global' +import { NormalizedPropsOptions } from './componentProps' +import { ObjectEmitsOptions } from './componentEmits' export interface App { version: string @@ -101,13 +103,19 @@ export interface AppContext { * Cache for merged/normalized component options * Each app instance has its own cache because app-level global mixins and * optionMergeStrategies can affect merge behavior. + * @internal */ - cache: WeakMap + optionsCache: WeakMap /** - * Flag for de-optimizing props normalization + * Cache for normalized props options * @internal */ - deopt?: boolean + propsCache: WeakMap + /** + * Cache for normalized emits options + * @internal + */ + emitsCache: WeakMap /** * HMR only * @internal @@ -144,7 +152,9 @@ export function createAppContext(): AppContext { components: {}, directives: {}, provides: Object.create(null), - cache: new WeakMap() + optionsCache: new WeakMap(), + propsCache: new WeakMap(), + emitsCache: new WeakMap() } } @@ -213,11 +223,6 @@ export function createAppAPI( if (__FEATURE_OPTIONS_API__) { if (!context.mixins.includes(mixin)) { context.mixins.push(mixin) - // global mixin with props/emits de-optimizes props/emits - // normalization caching. - if (mixin.props || mixin.emits) { - context.deopt = true - } } else if (__DEV__) { warn( 'Mixin has already been applied to target app' + diff --git a/packages/runtime-core/src/component.ts b/packages/runtime-core/src/component.ts index fd7b5777c9..78cabdd353 100644 --- a/packages/runtime-core/src/component.ts +++ b/packages/runtime-core/src/component.ts @@ -76,14 +76,6 @@ export interface AllowedComponentProps { // Note: can't mark this whole interface internal because some public interfaces // extend it. export interface ComponentInternalOptions { - /** - * @internal - */ - __props?: NormalizedPropsOptions - /** - * @internal - */ - __emits?: ObjectEmitsOptions | null /** * @internal */ diff --git a/packages/runtime-core/src/componentEmits.ts b/packages/runtime-core/src/componentEmits.ts index 44f9765dd9..b7fbec4899 100644 --- a/packages/runtime-core/src/componentEmits.ts +++ b/packages/runtime-core/src/componentEmits.ts @@ -172,8 +172,10 @@ export function normalizeEmitsOptions( appContext: AppContext, asMixin = false ): ObjectEmitsOptions | null { - if (!appContext.deopt && comp.__emits !== undefined) { - return comp.__emits + const cache = appContext.emitsCache + const cached = cache.get(comp) + if (cached !== undefined) { + return cached } const raw = comp.emits @@ -201,7 +203,8 @@ export function normalizeEmitsOptions( } if (!raw && !hasExtends) { - return (comp.__emits = null) + cache.set(comp, null) + return null } if (isArray(raw)) { @@ -209,7 +212,9 @@ export function normalizeEmitsOptions( } else { extend(normalized, raw) } - return (comp.__emits = normalized) + + cache.set(comp, normalized) + return normalized } // Check if an incoming prop key is a declared emit event listener. diff --git a/packages/runtime-core/src/componentOptions.ts b/packages/runtime-core/src/componentOptions.ts index 3983e8d94e..11c42fcd8e 100644 --- a/packages/runtime-core/src/componentOptions.ts +++ b/packages/runtime-core/src/componentOptions.ts @@ -894,7 +894,7 @@ export function resolveMergedOptions( const { mixins, extends: extendsOptions } = base const { mixins: globalMixins, - cache, + optionsCache: cache, config: { optionMergeStrategies } } = instance.appContext const cached = cache.get(base) diff --git a/packages/runtime-core/src/componentProps.ts b/packages/runtime-core/src/componentProps.ts index 3c9afc7c5c..b83f0abbe2 100644 --- a/packages/runtime-core/src/componentProps.ts +++ b/packages/runtime-core/src/componentProps.ts @@ -436,8 +436,10 @@ export function normalizePropsOptions( appContext: AppContext, asMixin = false ): NormalizedPropsOptions { - if (!appContext.deopt && comp.__props) { - return comp.__props + const cache = appContext.propsCache + const cached = cache.get(comp) + if (cached) { + return cached } const raw = comp.props @@ -468,7 +470,8 @@ export function normalizePropsOptions( } if (!raw && !hasExtends) { - return (comp.__props = EMPTY_ARR as any) + cache.set(comp, EMPTY_ARR as any) + return EMPTY_ARR as any } if (isArray(raw)) { @@ -506,7 +509,9 @@ export function normalizePropsOptions( } } - return (comp.__props = [normalized, needCastKeys]) + const res: NormalizedPropsOptions = [normalized, needCastKeys] + cache.set(comp, res) + return res } function validatePropName(key: string) {