Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

perf: unresolvedUrlToModule promise cache #12725

Merged
merged 2 commits into from Apr 6, 2023
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
77 changes: 45 additions & 32 deletions packages/vite/src/node/server/moduleGraph.ts
Expand Up @@ -64,11 +64,17 @@ export class ModuleGraph {
/**
* @internal
*/
_unresolvedUrlToModuleMap = new Map<string, ModuleNode>()
_unresolvedUrlToModuleMap = new Map<
string,
Promise<ModuleNode> | ModuleNode
>()
/**
* @internal
*/
_ssrUnresolvedUrlToModuleMap = new Map<string, ModuleNode>()
_ssrUnresolvedUrlToModuleMap = new Map<
string,
Promise<ModuleNode> | ModuleNode
>()

constructor(
private resolveId: (
Expand Down Expand Up @@ -255,37 +261,40 @@ export class ModuleGraph {
if (mod) {
return mod
}
const [url, resolvedId, meta] = await this._resolveUrl(
rawUrl,
ssr,
resolved,
)
mod = this.idToModuleMap.get(resolvedId)
if (!mod) {
mod = new ModuleNode(url, setIsSelfAccepting)
if (meta) mod.meta = meta
this.urlToModuleMap.set(url, mod)
mod.id = resolvedId
this.idToModuleMap.set(resolvedId, mod)
const file = (mod.file = cleanUrl(resolvedId))
let fileMappedModules = this.fileToModulesMap.get(file)
if (!fileMappedModules) {
fileMappedModules = new Set()
this.fileToModulesMap.set(file, fileMappedModules)
const modPromise = (async () => {
const [url, resolvedId, meta] = await this._resolveUrl(
rawUrl,
ssr,
resolved,
)
mod = this.idToModuleMap.get(resolvedId)
if (!mod) {
mod = new ModuleNode(url, setIsSelfAccepting)
if (meta) mod.meta = meta
this.urlToModuleMap.set(url, mod)
mod.id = resolvedId
this.idToModuleMap.set(resolvedId, mod)
const file = (mod.file = cleanUrl(resolvedId))
let fileMappedModules = this.fileToModulesMap.get(file)
if (!fileMappedModules) {
fileMappedModules = new Set()
this.fileToModulesMap.set(file, fileMappedModules)
}
fileMappedModules.add(mod)
}
fileMappedModules.add(mod)
}
// multiple urls can map to the same module and id, make sure we register
// the url to the existing module in that case
else if (!this.urlToModuleMap.has(url)) {
this.urlToModuleMap.set(url, mod)
}
// multiple urls can map to the same module and id, make sure we register
// the url to the existing module in that case
else if (!this.urlToModuleMap.has(url)) {
this.urlToModuleMap.set(url, mod)
}
this._setUnresolvedUrlToModule(rawUrl, mod, ssr)
return mod
})()

// Also register the clean url to the module, so that we can short-circuit
// resolving the same url twice
this._setUnresolvedUrlToModule(rawUrl, mod, ssr)

return mod
this._setUnresolvedUrlToModule(rawUrl, modPromise, ssr)
return modPromise
}

// some deps, like a css file referenced via @import, don't have its own
Expand Down Expand Up @@ -319,7 +328,7 @@ export class ModuleGraph {
// the same module
async resolveUrl(url: string, ssr?: boolean): Promise<ResolvedUrl> {
url = removeImportQuery(removeTimestampQuery(url))
const mod = this._getUnresolvedUrlToModule(url, ssr)
const mod = await this._getUnresolvedUrlToModule(url, ssr)
if (mod?.id) {
return [mod.url, mod.id, mod.meta]
}
Expand All @@ -332,15 +341,19 @@ export class ModuleGraph {
_getUnresolvedUrlToModule(
url: string,
ssr?: boolean,
): ModuleNode | undefined {
): Promise<ModuleNode> | ModuleNode | undefined {
return (
ssr ? this._ssrUnresolvedUrlToModuleMap : this._unresolvedUrlToModuleMap
).get(url)
}
/**
* @internal
*/
_setUnresolvedUrlToModule(url: string, mod: ModuleNode, ssr?: boolean): void {
_setUnresolvedUrlToModule(
url: string,
mod: Promise<ModuleNode> | ModuleNode,
ssr?: boolean,
): void {
;(ssr
? this._ssrUnresolvedUrlToModuleMap
: this._unresolvedUrlToModuleMap
Expand Down