Skip to content

Commit

Permalink
perf: chunk graph js api
Browse files Browse the repository at this point in the history
  • Loading branch information
SyMind committed Jan 10, 2025
1 parent 3a51cc9 commit e1feefb
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 37 deletions.
33 changes: 26 additions & 7 deletions packages/rspack/src/ChunkGraph.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,14 @@ import { Chunk } from "./Chunk";
import { Module } from "./Module";
import { DependenciesBlock } from "./DependenciesBlock";
import { ChunkGroup } from "./ChunkGroup";
import { VolatileMap } from "./util/volatile";

export class ChunkGraph {
#inner: JsChunkGraph;

#chunkModulesMap = new VolatileMap<Chunk, ReadonlyArray<Module>>();
#moduleIdMap = new VolatileMap<Module, string | null>();

static __from_binding(binding: JsChunkGraph): ChunkGraph {
return new ChunkGraph(binding);
}
Expand All @@ -17,15 +21,25 @@ export class ChunkGraph {
}

getChunkModules(chunk: Chunk): ReadonlyArray<Module> {
return this.#inner
.getChunkModules(Chunk.__to_binding(chunk))
.map(binding => Module.__from_binding(binding));
let modules = this.#chunkModulesMap.get(chunk);
if (modules === undefined) {
modules = this.#inner
.getChunkModules(Chunk.__to_binding(chunk))
.map(binding => Module.__from_binding(binding));
this.#chunkModulesMap.set(chunk, modules);
}
return modules;
}

getChunkModulesIterable(chunk: Chunk): Iterable<Module> {
return this.#inner
.getChunkModules(Chunk.__to_binding(chunk))
.map(binding => Module.__from_binding(binding));
let modules = this.#chunkModulesMap.get(chunk);
if (modules === undefined) {
modules = this.#inner
.getChunkModules(Chunk.__to_binding(chunk))
.map(binding => Module.__from_binding(binding));
this.#chunkModulesMap.set(chunk, modules);
}
return modules;
}

getChunkEntryModulesIterable(chunk: Chunk): Iterable<Module> {
Expand Down Expand Up @@ -65,7 +79,12 @@ export class ChunkGraph {
}

getModuleId(module: Module): string | null {
return this.#inner.getModuleId(Module.__to_binding(module));
let moduleId = this.#moduleIdMap.get(module);
if (moduleId === undefined) {
moduleId = this.#inner.getModuleId(Module.__to_binding(module));
this.#moduleIdMap.set(module, moduleId);
}
return moduleId;
}

getBlockChunkGroup(depBlock: DependenciesBlock): ChunkGroup | null {
Expand Down
10 changes: 9 additions & 1 deletion packages/rspack/src/ChunkGroup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import type { JsChunkGroup } from "@rspack/binding";

import { Chunk } from "./Chunk";
import { Module } from "./Module";
import { VolatileValue } from "./util/volatile";

const CHUNK_GROUP_MAPPINGS = new WeakMap<JsChunkGroup, ChunkGroup>();

Expand All @@ -14,6 +15,8 @@ export class ChunkGroup {

#inner: JsChunkGroup;

#name = new VolatileValue<string | undefined>();

static __from_binding(binding: JsChunkGroup) {
let chunkGroup = CHUNK_GROUP_MAPPINGS.get(binding);
if (chunkGroup) {
Expand Down Expand Up @@ -45,7 +48,12 @@ export class ChunkGroup {
name: {
enumerable: true,
get: () => {
return this.#inner.name;
if (this.#name.has()) {
return this.#name.get();
}
const name = this.#inner.name;
this.#name.set(name);
return name;
}
},
origins: {
Expand Down
2 changes: 1 addition & 1 deletion packages/rspack/src/Dependency.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ export class Dependency {

get ids(): string[] | null {
const binding = bindingDependencyFactory.getBinding(this);
if (this.#ids.get() !== undefined) {
if (this.#ids.has()) {
return this.#ids.get()!;
}
if (binding) {
Expand Down
52 changes: 27 additions & 25 deletions packages/rspack/src/ModuleGraph.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,17 +30,18 @@ export default class ModuleGraph {
}

getResolvedModule(dependency: Dependency): Module | null {
if (this.#resolvedModuleMap.get(dependency) !== undefined) {
return this.#resolvedModuleMap.get(dependency)!;
let resolvedModule = this.#resolvedModuleMap.get(dependency);
if (resolvedModule === undefined) {
const depBinding = bindingDependencyFactory.getBinding(dependency);
if (depBinding) {
const binding = this.#inner.getResolvedModule(depBinding);
resolvedModule = binding ? Module.__from_binding(binding) : null;
this.#resolvedModuleMap.set(dependency, resolvedModule);
} else {
return null;
}
}
const depBinding = bindingDependencyFactory.getBinding(dependency);
if (depBinding) {
const binding = this.#inner.getResolvedModule(depBinding);
const module = binding ? Module.__from_binding(binding) : null;
this.#resolvedModuleMap.set(dependency, module);
return module;
}
return null;
return resolvedModule;
}

getParentModule(dependency: Dependency): Module | null {
Expand Down Expand Up @@ -73,27 +74,28 @@ export default class ModuleGraph {
}

getOutgoingConnections(module: Module): ModuleGraphConnection[] {
if (this.#outgoingConnectionsMap.get(module)) {
return this.#outgoingConnectionsMap.get(module)!;
let connections = this.#outgoingConnectionsMap.get(module);
if (connections === undefined) {
connections = this.#inner
.getOutgoingConnections(Module.__to_binding(module))
.map(binding => ModuleGraphConnection.__from_binding(binding));
this.#outgoingConnectionsMap.set(module, connections);
}
const connections = this.#inner
.getOutgoingConnections(Module.__to_binding(module))
.map(binding => ModuleGraphConnection.__from_binding(binding));
this.#outgoingConnectionsMap.set(module, connections);
return connections;
}

getParentBlockIndex(dependency: Dependency): number {
if (this.#parentBlockIndexMap.get(dependency) !== undefined) {
return this.#parentBlockIndexMap.get(dependency)!;
}
const depBinding = bindingDependencyFactory.getBinding(dependency);
if (depBinding) {
const index = this.#inner.getParentBlockIndex(depBinding);
this.#parentBlockIndexMap.set(dependency, index);
return index;
let index = this.#parentBlockIndexMap.get(dependency);
if (index === undefined) {
const depBinding = bindingDependencyFactory.getBinding(dependency);
if (depBinding) {
index = this.#inner.getParentBlockIndex(depBinding);
this.#parentBlockIndexMap.set(dependency, index);
} else {
return -1;
}
}
return -1;
return index;
}

isAsync(module: Module): boolean {
Expand Down
2 changes: 1 addition & 1 deletion packages/rspack/src/ModuleGraphConnection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export class ModuleGraphConnection {
module: {
enumerable: true,
get: (): Module | null => {
if (this.#module.get() !== undefined) {
if (this.#module.has()) {
return this.#module.get()!;
}
const module = binding.module
Expand Down
13 changes: 11 additions & 2 deletions packages/rspack/src/util/volatile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ class MicrotaskQueue {
queue(callback: () => void) {
if (this.#callbacks.length === 0) {
queueMicrotask(() => {
for (const cb of this.#callbacks) {
const callbacks = this.#callbacks;
this.#callbacks = [];
for (const cb of callbacks) {
cb();
}
});
Expand Down Expand Up @@ -37,18 +39,25 @@ export class VolatileMap<K, V> {
}

export class VolatileValue<V> {
#setted = false;
#value: V | undefined = undefined;

get(): V | undefined {
return this.#value;
}

set(value: V) {
if (this.#value === undefined) {
if (!this.#setted) {
GLOBAL_MICROTASK_QUEUE.queue(() => {
this.#value = undefined;
this.#setted = false;
});
}
this.#value = value;
this.#setted = true;
}

has() {
return this.#setted;
}
}

0 comments on commit e1feefb

Please sign in to comment.