Visitar URL original
test(@angular/build): add massive-multichunk benchmark scenario · angular/angular-cli@8c273b0 · GitHub
Skip to content

Commit 8c273b0

Browse files
committed
test(@angular/build): add massive-multichunk benchmark scenario
Adds a new benchmark scenario modeling a very large application workload: - 800 chunks total (~150 MB JS): 1 main bundle (6 MB) + 250 small chunks (40 KB) + 549 feature chunks (245 KB). - 8 locales, 5,000 translations, sourcemaps ON. This exercises worker thread pool queue capacity, task dispatch throughput, IPC messaging, and memory reclamation across hundreds of files in parallel.
1 parent 1dfb814 commit 8c273b0

1 file changed

Lines changed: 108 additions & 0 deletions

File tree

‎scripts/benchmarks/i18n/scenarios.mts‎

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -541,6 +541,113 @@ export function createLargeEnterpriseScenario(
541541
};
542542
}
543543

544+
/**
545+
* 7. Massive Multichunk Scenario:
546+
* 800 chunks total (~150 MB JS): 1 main bundle (6 MB) + 250 small chunks (40 KB) + 549 feature chunks (245 KB),
547+
* 8 locales, 5,000 translations, sourcemaps ON.
548+
* Stresses worker thread pool queue capacity, dispatch throughput, IPC messaging, and memory reclamation
549+
* across hundreds of parallel files.
550+
*/
551+
export function createMassiveMultichunkScenario(
552+
options: ScenarioFactoryOptions = {},
553+
): BenchmarkScenario {
554+
let workload: GeneratedWorkload | undefined;
555+
556+
return {
557+
name: 'massive-multichunk',
558+
description: 'Massive Multichunk: 800 chunks (~150 MB JS), 8 locales, sourcemaps ON',
559+
get inputSizeBytes() {
560+
return workload?.totalInputSizeBytes ?? 0;
561+
},
562+
get localeCount() {
563+
return DEFAULT_LOCALES_8.length;
564+
},
565+
async setup() {
566+
await initializeFixtures();
567+
const files: BuildOutputFile[] = [];
568+
const totalMessages = 5000;
569+
let messageOffset = 0;
570+
571+
// 1. Dominant entry bundle: 6 MB, 1,000 messages
572+
const mainMessages = 1000;
573+
const { codeFile: mainCode, mapFile: mainMap } = generateSyntheticBundle({
574+
filename: 'main.js',
575+
targetByteSize: 6 * 1024 * 1024,
576+
messageCount: mainMessages,
577+
withSourceMap: true,
578+
messageIdOffset: messageOffset,
579+
});
580+
files.push(mainCode);
581+
if (mainMap) {
582+
files.push(mainMap);
583+
}
584+
messageOffset += mainMessages;
585+
586+
// 2. Small route/dialog chunks (< 100 KB): 250 chunks x 40 KB = 10 MB, 1,000 messages (4 msgs/chunk)
587+
const smallChunkCount = 250;
588+
const smallChunkSizeBytes = 40 * 1024;
589+
const smallChunkMessages = 4;
590+
for (let i = 0; i < smallChunkCount; i++) {
591+
const { codeFile, mapFile } = generateSyntheticBundle({
592+
filename: `small_chunk_${i}.js`,
593+
targetByteSize: smallChunkSizeBytes,
594+
messageCount: smallChunkMessages,
595+
withSourceMap: true,
596+
messageIdOffset: messageOffset + i * smallChunkMessages,
597+
});
598+
files.push(codeFile);
599+
if (mapFile) {
600+
files.push(mapFile);
601+
}
602+
}
603+
messageOffset += smallChunkCount * smallChunkMessages;
604+
605+
// 3. Medium/large feature chunks: 549 chunks x 245 KB = ~134.5 MB, 3,000 messages
606+
const featureChunkCount = 549;
607+
const featureChunkSizeBytes = 245 * 1024;
608+
const remainingMessages = totalMessages - messageOffset;
609+
const messagesPerFeatureChunk = Math.max(
610+
1,
611+
Math.floor(remainingMessages / featureChunkCount),
612+
);
613+
for (let i = 0; i < featureChunkCount; i++) {
614+
const { codeFile, mapFile } = generateSyntheticBundle({
615+
filename: `feature_chunk_${i}.js`,
616+
targetByteSize: featureChunkSizeBytes,
617+
messageCount: messagesPerFeatureChunk,
618+
withSourceMap: true,
619+
messageIdOffset: messageOffset + i * messagesPerFeatureChunk,
620+
});
621+
files.push(codeFile);
622+
if (mapFile) {
623+
files.push(mapFile);
624+
}
625+
}
626+
627+
const locales = generateTranslations(DEFAULT_LOCALES_8, totalMessages);
628+
workload = {
629+
files,
630+
locales,
631+
totalInputSizeBytes: calculateInputSizeBytes(files),
632+
};
633+
},
634+
async run() {
635+
if (!workload) {
636+
return;
637+
}
638+
const inliner = new I18nInliner({
639+
missingTranslation: 'warning',
640+
maxConcurrency: options.concurrency,
641+
});
642+
try {
643+
await inliner.inlineAll(workload.files, workload.locales);
644+
} finally {
645+
await inliner.close();
646+
}
647+
},
648+
};
649+
}
650+
544651
export function getAllScenarios(options: ScenarioFactoryOptions = {}): BenchmarkScenario[] {
545652
return [
546653
createStandardAppScenario(options),
@@ -549,6 +656,7 @@ export function getAllScenarios(options: ScenarioFactoryOptions = {}): Benchmark
549656
createLargeEnterpriseScenario(options),
550657
createMonolithicScenario(options),
551658
createMultiDominantScenario(options),
659+
createMassiveMultichunkScenario(options),
552660
createPersistentCacheWarmScenario(options),
553661
];
554662
}

0 commit comments

Comments
 (0)