diff --git a/src/utils/chunkAssignment.ts b/src/utils/chunkAssignment.ts index d0c5746b7d1..87cb401903a 100644 --- a/src/utils/chunkAssignment.ts +++ b/src/utils/chunkAssignment.ts @@ -79,7 +79,7 @@ function analyzeModuleGraph(entries: Iterable): { for (const currentEntry of allEntries) { const modulesToHandle = new Set([currentEntry]); for (const module of modulesToHandle) { - getOrCreate(dependentEntriesByModule, module, () => new Set()).add(currentEntry); + getOrCreate(dependentEntriesByModule, module, getNewSet).add(currentEntry); for (const dependency of module.getDependenciesToBeIncluded()) { if (!(dependency instanceof ExternalModule)) { modulesToHandle.add(dependency); @@ -122,7 +122,7 @@ function getDynamicallyDependentEntriesByDynamicEntry( const dynamicDependentEntries = getOrCreate( dynamicallyDependentEntriesByDynamicEntry, dynamicEntry, - () => new Set() + getNewSet ); for (const importer of [ ...dynamicEntry.includedDynamicImporters, @@ -147,7 +147,7 @@ function assignEntryToStaticDependencies( const dynamicDependentEntries = dynamicallyDependentEntriesByDynamicEntry.get(entry); const modulesToHandle = new Set([entry]); for (const module of modulesToHandle) { - const assignedEntries = getOrCreate(assignedEntriesByModule, module, () => new Set()); + const assignedEntries = getOrCreate(assignedEntriesByModule, module, getNewSet); if ( dynamicDependentEntries && areEntriesContainedOrDynamicallyDependent( @@ -258,6 +258,7 @@ function getOptimizedChunks( ----- pure side effects small ${`${chunkPartition.small.pure.size}`.padEnd(5, ' ')} ${chunkPartition.small.sideEffect.size} big ${`${chunkPartition.big.pure.size}`.padEnd(5, ' ')} ${chunkPartition.big.sideEffect.size} +Unoptimized chunks contain ${getNumberOfCycles(chunkPartition)} cycles. `); console.log( @@ -274,7 +275,9 @@ small ${`${chunkPartition.small.pure.size}`.padEnd(5, ' ')} ${chunkPartition.sma console.log( `${chunkPartition.small.sideEffect.size} chunks smaller than ${prettyBytes( minChunkSize - )} with side effects remaining.\n` + )} with side effects remaining.\nGenerated chunks contain ${getNumberOfCycles( + chunkPartition + )} cycles.\n` ); console.log( @@ -292,7 +295,7 @@ small ${`${chunkPartition.small.pure.size}`.padEnd(5, ' ')} ${chunkPartition.sma console.log( `${chunkPartition.small.pure.size} pure chunks smaller than ${prettyBytes( minChunkSize - )} remaining.\n` + )} remaining.\nGenerated chunks contain ${getNumberOfCycles(chunkPartition)} cycles.\n` ); timeEnd('optimize chunks', 3); const result = [ @@ -376,6 +379,39 @@ function getPartitionedChunks( }; } +function getNumberOfCycles(partition: ChunkPartition) { + const parents = new Set(); + const analysedChunks = new Set(); + let cycles = 0; + + const analyseChunk = (chunk: ChunkDescription) => { + for (const dependency of chunk.dependencies) { + if (parents.has(dependency)) { + if (!analysedChunks.has(dependency)) { + cycles++; + } + continue; + } + parents.add(dependency); + analyseChunk(dependency); + } + analysedChunks.add(chunk); + }; + + for (const chunk of [ + ...partition.big.pure, + ...partition.big.sideEffect, + ...partition.small.pure, + ...partition.small.sideEffect + ]) { + if (!parents.has(chunk)) { + parents.add(chunk); + analyseChunk(chunk); + } + } + return cycles; +} + function sortChunksAndAddDependencies( chunkLists: ChunkDescription[][], chunkByModule: Map @@ -526,3 +562,7 @@ function mergeSignatures(sourceSignature: string, targetSignature: string): stri } return signature; } + +function getNewSet() { + return new Set(); +}