Skip to content

Commit 19480ca

Browse files
committed
perf: use new Empty() instead of Object.create(null) for performance
1 parent 828d4a4 commit 19480ca

File tree

23 files changed

+66
-52
lines changed

23 files changed

+66
-52
lines changed

packages/compiler-core/src/babelUtils.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import type {
1111
ObjectProperty,
1212
Program,
1313
} from '@babel/types'
14+
import { Empty } from '@vue/shared'
1415
import { walk } from 'estree-walker'
1516

1617
/**
@@ -27,7 +28,7 @@ export function walkIdentifiers(
2728
) => void,
2829
includeAll = false,
2930
parentStack: Node[] = [],
30-
knownIds: Record<string, number> = Object.create(null),
31+
knownIds: Record<string, number> = new Empty(),
3132
): void {
3233
if (__BROWSER__) {
3334
return

packages/compiler-core/src/transform.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import {
2222
} from './ast'
2323
import {
2424
EMPTY_OBJ,
25+
Empty,
2526
NOOP,
2627
PatchFlags,
2728
camelize,
@@ -187,7 +188,7 @@ export function createTransformContext(
187188
cached: [],
188189
constantCache: new WeakMap(),
189190
temps: 0,
190-
identifiers: Object.create(null),
191+
identifiers: new Empty(),
191192
scopes: {
192193
vFor: 0,
193194
vSlot: 0,

packages/compiler-sfc/src/compileScript.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import {
1111
type SFCScriptBlock,
1212
} from './parse'
1313
import type { ParserPlugin } from '@babel/parser'
14-
import { generateCodeFrame } from '@vue/shared'
14+
import { Empty, generateCodeFrame } from '@vue/shared'
1515
import type {
1616
ArrayPattern,
1717
CallExpression,
@@ -194,8 +194,8 @@ export function compileScript(
194194

195195
// metadata that needs to be returned
196196
// const ctx.bindingMetadata: BindingMetadata = {}
197-
const scriptBindings: Record<string, BindingTypes> = Object.create(null)
198-
const setupBindings: Record<string, BindingTypes> = Object.create(null)
197+
const scriptBindings: Record<string, BindingTypes> = new Empty()
198+
const setupBindings: Record<string, BindingTypes> = new Empty()
199199

200200
let defaultExport: Node | undefined
201201
let hasAwait = false

packages/compiler-sfc/src/script/context.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import type { CallExpression, Node, ObjectPattern, Program } from '@babel/types'
22
import type { SFCDescriptor } from '../parse'
3-
import { generateCodeFrame, isArray } from '@vue/shared'
3+
import { Empty, generateCodeFrame, isArray } from '@vue/shared'
44
import { type ParserPlugin, parse as babelParse } from '@babel/parser'
55
import type { ImportBinding, SFCScriptCompileOptions } from '../compileScript'
66
import type { PropsDestructureBindings } from './defineProps'
@@ -28,7 +28,7 @@ export class ScriptCompileContext {
2828
// import / type analysis
2929
scope?: TypeScope
3030
globalScopes?: TypeScope[]
31-
userImports: Record<string, ImportBinding> = Object.create(null)
31+
userImports: Record<string, ImportBinding> = new Empty()
3232

3333
// macros presence check
3434
hasDefinePropsCall = false
@@ -46,7 +46,7 @@ export class ScriptCompileContext {
4646
propsRuntimeDecl: Node | undefined
4747
propsTypeDecl: Node | undefined
4848
propsDestructureDecl: ObjectPattern | undefined
49-
propsDestructuredBindings: PropsDestructureBindings = Object.create(null)
49+
propsDestructuredBindings: PropsDestructureBindings = new Empty()
5050
propsDestructureRestId: string | undefined
5151
propsRuntimeDefaults: Node | undefined
5252

@@ -56,7 +56,7 @@ export class ScriptCompileContext {
5656
emitDecl: Node | undefined
5757

5858
// defineModel
59-
modelDecls: Record<string, ModelDecl> = Object.create(null)
59+
modelDecls: Record<string, ModelDecl> = new Empty()
6060

6161
// defineOptions
6262
optionsRuntimeDecl: Node | undefined

packages/compiler-sfc/src/script/definePropsDestructure.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import {
1919
unwrapTSNode,
2020
walkFunctionParams,
2121
} from '@vue/compiler-dom'
22-
import { genPropsAccessExp } from '@vue/shared'
22+
import { Empty, genPropsAccessExp } from '@vue/shared'
2323
import { isCallOf, resolveObjectKey } from './utils'
2424
import type { ScriptCompileContext } from './context'
2525
import { DEFINE_PROPS } from './defineProps'
@@ -103,12 +103,12 @@ export function transformDestructuredProps(
103103
return
104104
}
105105

106-
const rootScope: Scope = Object.create(null)
106+
const rootScope: Scope = new Empty()
107107
const scopeStack: Scope[] = [rootScope]
108108
let currentScope: Scope = rootScope
109109
const excludedIds = new WeakSet<Identifier>()
110110
const parentStack: Node[] = []
111-
const propsLocalToPublicMap: Record<string, string> = Object.create(null)
111+
const propsLocalToPublicMap: Record<string, string> = new Empty()
112112

113113
for (const key in ctx.propsDestructuredBindings) {
114114
const { local } = ctx.propsDestructuredBindings[key]

packages/compiler-sfc/src/script/resolveType.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ import {
3434
} from './utils'
3535
import { type ScriptCompileContext, resolveParserPlugins } from './context'
3636
import type { ImportBinding, SFCScriptCompileOptions } from '../compileScript'
37-
import { capitalize, hasOwn } from '@vue/shared'
37+
import { Empty, capitalize, hasOwn } from '@vue/shared'
3838
import { parse as babelParse } from '@babel/parser'
3939
import { parse } from '../parse'
4040
import { createCache } from '../cache'
@@ -111,14 +111,14 @@ export class TypeScope {
111111
public filename: string,
112112
public source: string,
113113
public offset: number = 0,
114-
public imports: Record<string, Import> = Object.create(null),
115-
public types: Record<string, ScopeTypeNode> = Object.create(null),
116-
public declares: Record<string, ScopeTypeNode> = Object.create(null),
114+
public imports: Record<string, Import> = new Empty(),
115+
public types: Record<string, ScopeTypeNode> = new Empty(),
116+
public declares: Record<string, ScopeTypeNode> = new Empty(),
117117
) {}
118118
isGenericScope = false
119-
resolvedImportSources: Record<string, string> = Object.create(null)
120-
exportedTypes: Record<string, ScopeTypeNode> = Object.create(null)
121-
exportedDeclares: Record<string, ScopeTypeNode> = Object.create(null)
119+
resolvedImportSources: Record<string, string> = new Empty()
120+
exportedTypes: Record<string, ScopeTypeNode> = new Empty()
121+
exportedDeclares: Record<string, ScopeTypeNode> = new Empty()
122122
}
123123

124124
export interface MaybeWithScope {
@@ -231,7 +231,7 @@ function innerResolveTypeElements(
231231
resolved.typeParameters &&
232232
node.typeParameters
233233
) {
234-
typeParams = Object.create(null)
234+
typeParams = new Empty()
235235
resolved.typeParameters.params.forEach((p, i) => {
236236
let param = typeParameters && typeParameters[p.name]
237237
if (!param) param = node.typeParameters!.params[i]
@@ -1442,7 +1442,7 @@ function attachNamespace(
14421442
}
14431443

14441444
export function recordImports(body: Statement[]): Record<string, Import> {
1445-
const imports: TypeScope['imports'] = Object.create(null)
1445+
const imports: TypeScope['imports'] = new Empty()
14461446
for (const s of body) {
14471447
recordImport(s, imports)
14481448
}

packages/compiler-sfc/src/style/pluginScoped.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,13 @@ import {
77
} from 'postcss'
88
import selectorParser from 'postcss-selector-parser'
99
import { warn } from '../warn'
10+
import { Empty } from '@vue/shared'
1011

1112
const animationNameRE = /^(-\w+-)?animation-name$/
1213
const animationRE = /^(-\w+-)?animation$/
1314

1415
const scopedPlugin: PluginCreator<string> = (id = '') => {
15-
const keyframes = Object.create(null)
16+
const keyframes = new Empty()
1617
const shortId = id.replace(/^data-v-/, '')
1718

1819
return {

packages/runtime-core/src/apiCreateApp.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import { warn } from './warning'
2222
import { type VNode, cloneVNode, createVNode } from './vnode'
2323
import type { RootHydrateFunction } from './hydration'
2424
import { devtoolsInitApp, devtoolsUnmountApp } from './devtools'
25-
import { NO, extend, isFunction, isObject } from '@vue/shared'
25+
import { Empty, NO, extend, isFunction, isObject } from '@vue/shared'
2626
import { version } from '.'
2727
import { installAppCompatProperties } from './compat/global'
2828
import type { NormalizedPropsOptions } from './componentProps'
@@ -234,7 +234,7 @@ export function createAppContext(): AppContext {
234234
mixins: [],
235235
components: {},
236236
directives: {},
237-
provides: Object.create(null),
237+
provides: new Empty(),
238238
optionsCache: new WeakMap(),
239239
propsCache: new WeakMap(),
240240
emitsCache: new WeakMap(),

packages/runtime-core/src/compat/compatConfig.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { extend, hasOwn, isArray, isFunction } from '@vue/shared'
1+
import { Empty, extend, hasOwn, isArray, isFunction } from '@vue/shared'
22
import {
33
type Component,
44
type ComponentInternalInstance,
@@ -425,8 +425,8 @@ export const deprecationData: Record<DeprecationTypes, DeprecationData> = {
425425
},
426426
}
427427

428-
const instanceWarned: Record<string, true> = Object.create(null)
429-
const warnCount: Record<string, number> = Object.create(null)
428+
const instanceWarned: Record<string, true> = new Empty()
429+
const warnCount: Record<string, number> = new Empty()
430430

431431
// test only
432432
let warningEnabled = true

packages/runtime-core/src/compat/global.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
trigger,
88
} from '@vue/reactivity'
99
import {
10+
Empty,
1011
NOOP,
1112
extend,
1213
invokeArrayFns,
@@ -259,7 +260,7 @@ export function createCompatVue(
259260
mergeBase[key] = isArray(superValue)
260261
? superValue.slice()
261262
: isObject(superValue)
262-
? extend(Object.create(null), superValue)
263+
? extend(new Empty(), superValue)
263264
: superValue
264265
}
265266

@@ -640,7 +641,7 @@ function defineReactive(obj: any, key: string, val: any) {
640641
if (i && obj === i.proxy) {
641642
// target is a Vue instance - define on instance.ctx
642643
defineReactiveSimple(i.ctx, key, val)
643-
i.accessCache = Object.create(null)
644+
i.accessCache = new Empty()
644645
} else if (isReactive(obj)) {
645646
obj[key] = val
646647
} else {

0 commit comments

Comments
 (0)