Skip to content

Commit a01747c

Browse files
Connor ClarkDevtools-frontend LUCI CQ
authored andcommitted
[RPP] Group duplicated modules by node_modules package
Bug: 394373632 Change-Id: I6bec9980e7ad141c030ec12b9d6b8e2047327628 Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/6370582 Reviewed-by: Paul Irish <[email protected]> Auto-Submit: Connor Clark <[email protected]> Commit-Queue: Connor Clark <[email protected]>
1 parent 6f7358c commit a01747c

File tree

2 files changed

+73
-8
lines changed

2 files changed

+73
-8
lines changed

front_end/models/trace/extras/ScriptDuplication.test.ts

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,10 @@ describeWithEnvironment('ScriptDuplication', function() {
269269
{scriptId: '1.coursehero-bundle-2', resourceSize: 5840},
270270
{scriptId: '1.coursehero-bundle-1', resourceSize: 5316}
271271
],
272+
'node_modules/@babel/runtime': [
273+
{scriptId: '1.coursehero-bundle-1', resourceSize: 6929},
274+
{scriptId: '1.coursehero-bundle-2', resourceSize: 4811},
275+
],
272276
'coursehero:///js/src/search/results/view/filter/autocomplete-filter.tsx': [
273277
{scriptId: '1.coursehero-bundle-1', resourceSize: 3823},
274278
{scriptId: '1.coursehero-bundle-2', resourceSize: 3812}
@@ -281,6 +285,10 @@ describeWithEnvironment('ScriptDuplication', function() {
281285
{scriptId: '1.coursehero-bundle-1', resourceSize: 2696},
282286
{scriptId: '1.coursehero-bundle-2', resourceSize: 2693}
283287
],
288+
'node_modules/lodash-es': [
289+
{scriptId: '1.coursehero-bundle-2', resourceSize: 4384},
290+
{scriptId: '1.coursehero-bundle-1', resourceSize: 2489},
291+
],
284292
'coursehero:///js/src/utils/service/amplitude-service.ts': [
285293
{scriptId: '1.coursehero-bundle-1', resourceSize: 1348},
286294
{scriptId: '1.coursehero-bundle-2', resourceSize: 1325}
@@ -289,9 +297,6 @@ describeWithEnvironment('ScriptDuplication', function() {
289297
{scriptId: '1.coursehero-bundle-2', resourceSize: 1143},
290298
{scriptId: '1.coursehero-bundle-1', resourceSize: 1134}
291299
],
292-
'node_modules/@babel/runtime/helpers/typeof.js': [
293-
{scriptId: '1.coursehero-bundle-1', resourceSize: 992}, {scriptId: '1.coursehero-bundle-2', resourceSize: 992}
294-
],
295300
'coursehero:///js/src/search/results/store/filter-actions.ts': [
296301
{scriptId: '1.coursehero-bundle-2', resourceSize: 956}, {scriptId: '1.coursehero-bundle-1', resourceSize: 946}
297302
],
@@ -301,15 +306,12 @@ describeWithEnvironment('ScriptDuplication', function() {
301306
'coursehero:///js/src/utils/service/gsa-inmeta-tags.ts': [
302307
{scriptId: '1.coursehero-bundle-1', resourceSize: 591}, {scriptId: '1.coursehero-bundle-2', resourceSize: 563}
303308
],
304-
'node_modules/@babel/runtime/helpers/inherits.js': [
305-
{scriptId: '1.coursehero-bundle-1', resourceSize: 528}, {scriptId: '1.coursehero-bundle-2', resourceSize: 528}
306-
],
307309
'coursehero:///js/src/search/results/service/api/filter-api-service.ts': [
308310
{scriptId: '1.coursehero-bundle-1', resourceSize: 554}, {scriptId: '1.coursehero-bundle-2', resourceSize: 534}
309311
],
310312
'coursehero:///js/src/common/component/search/course-search.tsx': [
311313
{scriptId: '1.coursehero-bundle-2', resourceSize: 545}, {scriptId: '1.coursehero-bundle-1', resourceSize: 544}
312-
]
314+
],
313315
});
314316
});
315317
});
@@ -376,4 +378,20 @@ describeWithEnvironment('ScriptDuplication', function() {
376378
assert.strictEqual(Trace.Extras.ScriptDuplication.normalizeSource(input), expected);
377379
}
378380
});
381+
382+
it('getNodeModuleName', () => {
383+
const testCases = [
384+
['node_modules/package/othermodule.js', 'package'],
385+
['node_modules/somemodule/node_modules/package/othermodule.js', 'package'],
386+
[
387+
'node_modules/somemodule/node_modules/somemodule2/node_modules/somemodule2/othermodule.js',
388+
'somemodule2',
389+
],
390+
['node_modules/@lh/ci', '@lh/ci'],
391+
['node_modules/blahblah/node_modules/@lh/ci', '@lh/ci'],
392+
];
393+
for (const [input, expected] of testCases) {
394+
assert.strictEqual(Trace.Extras.ScriptDuplication.getNodeModuleName(input), expected);
395+
}
396+
});
379397
});

front_end/models/trace/extras/ScriptDuplication.ts

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,52 @@ export function normalizeDuplication(duplication: ScriptDuplication): void {
176176
}
177177
}
178178

179+
function indexOfOrLength(haystack: string, needle: string, startPosition = 0): number {
180+
const index = haystack.indexOf(needle, startPosition);
181+
return index === -1 ? haystack.length : index;
182+
}
183+
184+
export function getNodeModuleName(source: string): string {
185+
const sourceSplit = source.split('node_modules/');
186+
source = sourceSplit[sourceSplit.length - 1];
187+
188+
const indexFirstSlash = indexOfOrLength(source, '/');
189+
if (source[0] === '@') {
190+
return source.slice(0, indexOfOrLength(source, '/', indexFirstSlash + 1));
191+
}
192+
193+
return source.slice(0, indexFirstSlash);
194+
}
195+
196+
function groupByNodeModules(duplication: ScriptDuplication): ScriptDuplication {
197+
const groupedDuplication: ScriptDuplication = new Map();
198+
for (const [source, data] of duplication.entries()) {
199+
if (!source.includes('node_modules')) {
200+
groupedDuplication.set(source, data);
201+
continue;
202+
}
203+
204+
const nodeModuleKey = 'node_modules/' + getNodeModuleName(source);
205+
const aggregatedData = groupedDuplication.get(nodeModuleKey) ?? {
206+
duplicates: [],
207+
// This is calculated in normalizeDuplication.
208+
estimatedDuplicateBytes: 0,
209+
};
210+
groupedDuplication.set(nodeModuleKey, aggregatedData);
211+
212+
for (const {script, attributedSize} of data.duplicates) {
213+
let duplicate = aggregatedData.duplicates.find(d => d.script === script);
214+
if (!duplicate) {
215+
duplicate = {script, attributedSize: 0};
216+
aggregatedData.duplicates.push(duplicate);
217+
}
218+
duplicate.attributedSize += attributedSize;
219+
}
220+
}
221+
222+
return groupedDuplication;
223+
}
224+
179225
function computeLastGeneratedColumnMap(map: SDK.SourceMap.SourceMap): Map<SDK.SourceMap.SourceMapEntry, number> {
180226
const result = new Map<SDK.SourceMap.SourceMapEntry, number>();
181227

@@ -233,7 +279,7 @@ export function computeScriptDuplication(scriptsData: Handlers.ModelHandlers.Scr
233279
}
234280
}
235281

236-
const duplication: ScriptDuplication = new Map();
282+
let duplication: ScriptDuplication = new Map();
237283
for (const [script, sourceDataArray] of sourceDatasMap) {
238284
for (const sourceData of sourceDataArray) {
239285
let data = duplication.get(sourceData.source);
@@ -248,6 +294,7 @@ export function computeScriptDuplication(scriptsData: Handlers.ModelHandlers.Scr
248294
}
249295
}
250296

297+
duplication = groupByNodeModules(duplication);
251298
normalizeDuplication(duplication);
252299

253300
// Sort by estimated savings.

0 commit comments

Comments
 (0)