Skip to content

Commit 59b3916

Browse files
Adriana IxbaDevtools-frontend LUCI CQ
authored andcommitted
[RPP] Set up 3p cache
This starts building the caches from the NetworkHandler down to the RendererHandler. Also moves URLForEntry so that it could be depended on by the Handlers. This is not yet used anywhere, but this sets the data that we need to be referenced in follow up features like the checkbox, summary details table, etc. This also doesn't yet handle keeping the cache up to date via sourceMaps, this will be worked through on a separate cl Bug:381960419 Change-Id: I9629f5a511908166ad104aad37b2590c04b0a23f Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/6069068 Reviewed-by: Adam Raine <[email protected]> Commit-Queue: Adriana Ixba <[email protected]>
1 parent b333000 commit 59b3916

24 files changed

+575
-184
lines changed

config/gni/devtools_grd_files.gni

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1051,7 +1051,6 @@ grd_files_debug_sources = [
10511051
"front_end/models/trace/extras/TimelineJSProfile.js",
10521052
"front_end/models/trace/extras/TraceFilter.js",
10531053
"front_end/models/trace/extras/TraceTree.js",
1054-
"front_end/models/trace/extras/URLForEntry.js",
10551054
"front_end/models/trace/handlers/AnimationFramesHandler.js",
10561055
"front_end/models/trace/handlers/AnimationHandler.js",
10571056
"front_end/models/trace/handlers/AsyncJSCallsHandler.js",
@@ -1083,6 +1082,7 @@ grd_files_debug_sources = [
10831082
"front_end/models/trace/handlers/UserTimingsHandler.js",
10841083
"front_end/models/trace/handlers/WarningsHandler.js",
10851084
"front_end/models/trace/handlers/WorkersHandler.js",
1085+
"front_end/models/trace/handlers/helpers.js",
10861086
"front_end/models/trace/handlers/types.js",
10871087
"front_end/models/trace/helpers/Extensions.js",
10881088
"front_end/models/trace/helpers/Network.js",
@@ -1897,6 +1897,7 @@ grd_files_debug_sources = [
18971897
"front_end/panels/timeline/timelinePanel.css.js",
18981898
"front_end/panels/timeline/timelineStatusDialog.css.js",
18991899
"front_end/panels/timeline/utils/AICallTree.js",
1900+
"front_end/panels/timeline/utils/EntityMapper.js",
19001901
"front_end/panels/timeline/utils/EntryName.js",
19011902
"front_end/panels/timeline/utils/EntryStyles.js",
19021903
"front_end/panels/timeline/utils/Helpers.js",

front_end/models/trace/Processor.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ describeWithEnvironment('TraceProcessor', function() {
118118
Renderer: Trace.Handlers.ModelHandlers.Renderer,
119119
Samples: Trace.Handlers.ModelHandlers.Samples,
120120
AuctionWorklets: Trace.Handlers.ModelHandlers.AuctionWorklets,
121+
NetworkRequests: Trace.Handlers.ModelHandlers.NetworkRequests,
121122
},
122123
Trace.Types.Configuration.defaults());
123124

front_end/models/trace/extras/BUILD.gn

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ devtools_module("extras") {
1818
"TimelineJSProfile.ts",
1919
"TraceFilter.ts",
2020
"TraceTree.ts",
21-
"URLForEntry.ts",
2221
]
2322

2423
deps = [
@@ -53,7 +52,6 @@ ts_library("unittests") {
5352
"ThirdParties.test.ts",
5453
"TraceFilter.test.ts",
5554
"TraceTree.test.ts",
56-
"URLForEntry.test.ts",
5755
]
5856

5957
deps = [

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

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -8,33 +8,6 @@ import * as Trace from '../trace.js';
88

99
describeWithEnvironment('ThirdParties', function() {
1010
describe('Entities', function() {
11-
it('correctly makes up entities', async function() {
12-
const expectedEntities = new Map<string, string>([
13-
['http://localhost:8080/', 'localhost'],
14-
['https://fonts.googleapis.com/css2?family=Orelega+One&display=swap', 'googleapis.com'],
15-
['https://emp.bbci.co.uk/emp/bump-4/bump-4.js', 'bbci.co.uk'],
16-
['http://localhost:8080/blocking.js', 'localhost'],
17-
['https://fonts.gstatic.com/s/orelegaone/v1/3qTpojOggD2XtAdFb-QXZFt93kY.woff2', 'gstatic.com'],
18-
['chrome-extension://chromeextension/something/exciting.js', 'chromeextension'],
19-
]);
20-
21-
for (const [url, expectedEntity] of expectedEntities.entries()) {
22-
const gotEntity =
23-
Trace.Extras.ThirdParties.makeUpEntity(new Map<string, Trace.Extras.ThirdParties.Entity>(), url)?.name ??
24-
'';
25-
assert.deepEqual(gotEntity, expectedEntity);
26-
}
27-
});
28-
it('coreectly makes up chrome extension entity', async function() {
29-
const url = 'chrome-extension://chromeextension/something/exciting.js';
30-
const gotEntity =
31-
Trace.Extras.ThirdParties.makeUpEntity(new Map<string, Trace.Extras.ThirdParties.Entity>(), url);
32-
assert.exists(gotEntity);
33-
34-
assert.deepEqual(gotEntity.name, 'chromeextension');
35-
assert.deepEqual(gotEntity.category, 'Chrome Extension');
36-
assert.deepEqual(gotEntity.homepage, 'https://chromewebstore.google.com/detail/chromeextension');
37-
});
3811
it('gets correct entitiesByRequest', async function() {
3912
const {parsedTrace} = await TraceLoader.traceEngine(this, 'load-simple.json.gz');
4013
const reqs = parsedTrace.NetworkRequests.byTime;

front_end/models/trace/extras/ThirdParties.ts

Lines changed: 3 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,10 @@
33
// found in the LICENSE file.
44

55
import * as ThirdPartyWeb from '../../../third_party/third-party-web/third-party-web.js';
6-
import type * as Handlers from '../handlers/handlers.js';
6+
import * as Handlers from '../handlers/handlers.js';
77
import * as Helpers from '../helpers/helpers.js';
88
import * as Types from '../types/types.js';
99

10-
import * as URLForEntry from './URLForEntry.js';
11-
1210
export type Entity = typeof ThirdPartyWeb.ThirdPartyWeb.entities[number];
1311

1412
export interface Summary {
@@ -22,77 +20,6 @@ export interface SummaryMaps {
2220
requestsByEntity: Map<Entity, Types.Events.SyntheticNetworkRequest[]>;
2321
}
2422

25-
/**
26-
* Returns the origin portion of a Chrome extension URL.
27-
*/
28-
function getChromeExtensionOrigin(url: URL): string {
29-
return url.protocol + '//' + url.host;
30-
}
31-
32-
function makeUpChromeExtensionEntity(entityCache: Map<string, Entity>, url: string, extensionName?: string): Entity {
33-
const parsedUrl = new URL(url);
34-
const origin = getChromeExtensionOrigin(parsedUrl);
35-
const host = new URL(origin).host;
36-
const name = extensionName || host;
37-
38-
const cachedEntity = entityCache.get(origin);
39-
if (cachedEntity) {
40-
return cachedEntity;
41-
}
42-
43-
const chromeExtensionEntity = {
44-
name,
45-
company: name,
46-
category: 'Chrome Extension',
47-
homepage: 'https://chromewebstore.google.com/detail/' + host,
48-
categories: [],
49-
domains: [],
50-
averageExecutionTime: 0,
51-
totalExecutionTime: 0,
52-
totalOccurrences: 0,
53-
};
54-
55-
entityCache.set(origin, chromeExtensionEntity);
56-
return chromeExtensionEntity;
57-
}
58-
59-
export function makeUpEntity(entityCache: Map<string, Entity>, url: string): Entity|undefined {
60-
if (url.startsWith('chrome-extension:')) {
61-
return makeUpChromeExtensionEntity(entityCache, url);
62-
}
63-
64-
// Make up an entity only for valid http/https URLs.
65-
if (!url.startsWith('http')) {
66-
return;
67-
}
68-
69-
// NOTE: Lighthouse uses a tld database to determine the root domain, but here
70-
// we are using third party web's database. Doesn't really work for the case of classifying
71-
// domains 3pweb doesn't know about, so it will just give us a guess.
72-
const rootDomain = ThirdPartyWeb.ThirdPartyWeb.getRootDomain(url);
73-
if (!rootDomain) {
74-
return;
75-
}
76-
77-
if (entityCache.has(rootDomain)) {
78-
return entityCache.get(rootDomain);
79-
}
80-
81-
const unrecognizedEntity = {
82-
name: rootDomain,
83-
company: rootDomain,
84-
category: '',
85-
categories: [],
86-
domains: [rootDomain],
87-
averageExecutionTime: 0,
88-
totalExecutionTime: 0,
89-
totalOccurrences: 0,
90-
isUnrecognized: true,
91-
};
92-
entityCache.set(rootDomain, unrecognizedEntity);
93-
return unrecognizedEntity;
94-
}
95-
9623
function getSelfTimeByUrl(
9724
parsedTrace: Handlers.Types.ParsedTrace, bounds: Types.Timing.TraceWindowMicroSeconds): Map<string, number> {
9825
const selfTimeByUrl = new Map<string, number>();
@@ -118,7 +45,7 @@ function getSelfTimeByUrl(
11845
continue;
11946
}
12047

121-
const url = URLForEntry.getNonResolved(parsedTrace as Handlers.Types.ParsedTrace, event);
48+
const url = Handlers.Helpers.getNonResolvedURL(event, parsedTrace as Handlers.Types.ParsedTrace);
12249
if (!url) {
12350
continue;
12451
}
@@ -138,7 +65,7 @@ export function getEntitiesByRequest(requests: Types.Events.SyntheticNetworkRequ
13865
const madeUpEntityCache = new Map<string, Entity>();
13966
for (const request of requests) {
14067
const url = request.args.data.url;
141-
const entity = ThirdPartyWeb.ThirdPartyWeb.getEntity(url) ?? makeUpEntity(madeUpEntityCache, url);
68+
const entity = ThirdPartyWeb.ThirdPartyWeb.getEntity(url) ?? Handlers.Helpers.makeUpEntity(madeUpEntityCache, url);
14269
if (entity) {
14370
entityByRequest.set(request, entity);
14471
}

front_end/models/trace/extras/URLForEntry.ts

Lines changed: 0 additions & 56 deletions
This file was deleted.

front_end/models/trace/extras/extras.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,3 @@ export * as ThirdParties from './ThirdParties.js';
1111
export * as TimelineJSProfile from './TimelineJSProfile.js';
1212
export * as TraceFilter from './TraceFilter.js';
1313
export * as TraceTree from './TraceTree.js';
14-
export * as URLForEntry from './URLForEntry.js';

front_end/models/trace/handlers/BUILD.gn

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,14 @@ devtools_module("handlers") {
4040
"UserTimingsHandler.ts",
4141
"WarningsHandler.ts",
4242
"WorkersHandler.ts",
43+
"helpers.ts",
4344
"types.ts",
4445
]
4546

4647
deps = [
4748
"../../../core/platform:bundle",
4849
"../../../generated",
50+
"../../../third_party/third-party-web:bundle",
4951
"../../cpu_profile:bundle",
5052
"../helpers:bundle",
5153
"../types:bundle",
@@ -97,6 +99,7 @@ ts_library("unittests") {
9799
"UserTimingsHandler.test.ts",
98100
"WarningsHandler.test.ts",
99101
"WorkersHandler.test.ts",
102+
"helpers.test.ts",
100103
]
101104

102105
deps = [

front_end/models/trace/handlers/NetworkRequestsHandler.test.ts

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,112 @@ describe('NetworkRequestsHandler', function() {
342342
assert.strictEqual(initiator.args.data.url, event.args.data.stackTrace?.[0].url);
343343
});
344344
});
345+
describe('ThirdParty caches', () => {
346+
it('Correctly captures entities by network event', async function() {
347+
const traceEvents = await TraceLoader.rawEvents(this, 'lantern/paul/trace.json.gz');
348+
for (const event of traceEvents) {
349+
Trace.Handlers.ModelHandlers.Meta.handleEvent(event);
350+
Trace.Handlers.ModelHandlers.NetworkRequests.handleEvent(event);
351+
}
352+
await Trace.Handlers.ModelHandlers.Meta.finalize();
353+
await Trace.Handlers.ModelHandlers.NetworkRequests.finalize();
354+
355+
const {entityMappings} = Trace.Handlers.ModelHandlers.NetworkRequests.data();
356+
const syntheticNetworkEventsByEntity = new Map(
357+
Array.from(entityMappings.eventsByEntity.entries()).map(([entity, events]) => {
358+
const syntheticNetworkEvents = events.filter(
359+
event => Trace.Types.Events.isSyntheticNetworkRequest(event),
360+
);
361+
return [entity, syntheticNetworkEvents];
362+
}),
363+
);
364+
const requestsByEntityResult = [...syntheticNetworkEventsByEntity.entries()].map(([entity, requests]) => {
365+
return [entity.name, requests.map(r => r.args?.data?.url)];
366+
});
367+
assert.deepEqual(
368+
requestsByEntityResult,
369+
[
370+
[
371+
'paulirish.com',
372+
[
373+
'https://www.paulirish.com/',
374+
'https://www.paulirish.com/assets/wikipedia-flamechart.jpg',
375+
'https://www.paulirish.com/avatar150.jpg',
376+
'https://www.paulirish.com/javascripts/modernizr-2.0.js',
377+
'https://www.paulirish.com/javascripts/ender.js',
378+
'https://www.paulirish.com/javascripts/octopress.js',
379+
'https://www.paulirish.com/javascripts/firebase-performance-standalone.js',
380+
'https://www.paulirish.com/images/noise.png?1418840251',
381+
'https://www.paulirish.com/images/code_bg.png?1418840251',
382+
'https://www.paulirish.com/favicon.ico',
383+
],
384+
],
385+
[
386+
'Google Tag Manager',
387+
[
388+
'https://www.googletagmanager.com/gtag/js?id=G-PGXNGYWP8E',
389+
],
390+
],
391+
[
392+
'Google Fonts',
393+
[
394+
'https://fonts.googleapis.com/css?family=PT+Serif:regular,italic,bold|PT+Sans:regular,italic,bold|Droid+Sans:400,700|Lato:700,900',
395+
'https://fonts.gstatic.com/s/droidsans/v18/SlGVmQWMvZQIdix7AFxXkHNSbRYXags.woff2',
396+
'https://fonts.gstatic.com/s/lato/v24/S6u9w4BMUTPHh6UVSwiPGQ3q5d0.woff2',
397+
'https://fonts.gstatic.com/s/ptsans/v17/jizaRExUiTo99u79D0KExcOPIDU.woff2',
398+
'https://fonts.gstatic.com/s/ptsans/v17/jizfRExUiTo99u79B_mh0O6tLR8a8zI.woff2',
399+
'https://fonts.gstatic.com/s/droidsans/v18/SlGWmQWMvZQIdix7AFxXmMh3eDs1ZyHKpWg.woff2',
400+
'https://fonts.gstatic.com/s/ptserif/v18/EJRVQgYoZZY2vCFuvAFWzr-_dSb_.woff2',
401+
],
402+
],
403+
[
404+
'Google Analytics',
405+
[
406+
'https://www.google-analytics.com/analytics.js',
407+
'https://www.google-analytics.com/g/collect?v=2&tid=G-PGXNGYWP8E&gtm=45je4580v880158425za200&_p=1715625261583&gcd=13l3l3l3l1&npa=0&dma=0&cid=414801335.1715625262&ul=en-us&sr=412x823&uaa=&uab=64&uafvl=Not%252FA)Brand%3B8.0.0.0%7CChromium%3B126.0.6475.0%7CGoogle%2520Chrome%3B126.0.6475.0&uamb=1&uam=moto%20g%20power%20(2022)&uap=Android&uapv=11.0&uaw=0&are=1&frm=0&pscdl=noapi&_s=1&sid=1715625261&sct=1&seg=0&dl=https%3A%2F%2Fwww.paulirish.com%2F&dt=Paul%20Irish&en=page_view&_fv=1&_nsi=1&_ss=1&_ee=1&tfd=353',
408+
'https://www.google-analytics.com/j/collect?v=1&_v=j101&a=272264939&t=pageview&_s=1&dl=https%3A%2F%2Fwww.paulirish.com%2F&ul=en-us&de=UTF-8&dt=Paul%20Irish&sd=30-bit&sr=412x823&vp=412x823&je=0&_u=IADAAEABAAAAACAAI~&jid=1388679807&gjid=654531532&cid=414801335.1715625262&tid=UA-692547-2&_gid=1964734610.1715625262&_r=1&_slc=1&z=1746264594',
409+
],
410+
],
411+
[
412+
'Disqus',
413+
[
414+
'https://paulirish.disqus.com/count.js',
415+
],
416+
],
417+
[
418+
'Firebase',
419+
[
420+
'https://firebaseinstallations.googleapis.com/v1/projects/paulirishcom/installations',
421+
'https://firebaseremoteconfig.googleapis.com/v1/projects/paulirishcom/namespaces/fireperf:fetch?key=AIzaSyCGxLbbFQxH4BV1fY0RODlxTos9nJa2l_g',
422+
],
423+
],
424+
],
425+
);
426+
});
427+
it('Correctly captures entities', async function() {
428+
const traceEvents = await TraceLoader.rawEvents(this, 'lantern/paul/trace.json.gz');
429+
for (const event of traceEvents) {
430+
Trace.Handlers.ModelHandlers.Meta.handleEvent(event);
431+
Trace.Handlers.ModelHandlers.NetworkRequests.handleEvent(event);
432+
}
433+
await Trace.Handlers.ModelHandlers.Meta.finalize();
434+
await Trace.Handlers.ModelHandlers.NetworkRequests.finalize();
435+
436+
const {entityMappings} = Trace.Handlers.ModelHandlers.NetworkRequests.data();
437+
const expectedEntities = [
438+
'paulirish.com',
439+
'Google Tag Manager',
440+
'Google Fonts',
441+
'Google Analytics',
442+
'Disqus',
443+
'Firebase',
444+
];
445+
const gotEntities = Array.from(entityMappings.entityByEvent.values()).map(enity => enity.name);
446+
expectedEntities.forEach(entity => {
447+
assert.isTrue(gotEntities.includes(entity));
448+
});
449+
});
450+
});
345451
});
346452

347453
function assertDataArgsStats<D extends keyof DataArgs>(

0 commit comments

Comments
 (0)