Skip to content

Commit 90505a6

Browse files
authored
Merge pull request #16 from PerfLab-io/add-thirdparty-overlay-event
Add thirdparty overlay event
2 parents cfcd2dc + 1d3f0d4 commit 90505a6

File tree

1 file changed

+164
-0
lines changed

1 file changed

+164
-0
lines changed

front_end/panels/timeline/TimelinePanel.ts

Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -454,6 +454,126 @@ export class TimelinePanel extends UI.Panel.Panel implements Client, TimelineMod
454454
this.#setActiveInsight({name, navigationId, createOverlayFn});
455455
});
456456

457+
// Custom event to show third-party scripts as overlay. Extracted from ThirdParties.ts
458+
// @ts-expect-error
459+
document.getElementById('-blink-dev-tools')?.addEventListener(ShowThirdPartiesEvent.eventName, (event: ShowThirdPartiesEvent) => {
460+
const {navigationId, filterByThirdParty, filterByTimestamp} = event.detail;
461+
this.#setActiveInsight({
462+
name: 'third-parties',
463+
navigationId,
464+
createOverlayFn: () => {
465+
// We should have the current active trace index on the model loaded
466+
const traceInsightsData = this.#traceEngineModel.traceInsights(this.#activeTraceIndex() || 0);
467+
const insight = TimelineInsights.ThirdParties.getThirdPartiesInsight(traceInsightsData, navigationId);
468+
if (!insight) {
469+
return [];
470+
}
471+
472+
const overlays: Overlays.Overlays.TimelineOverlay[] = [];
473+
for (const [entity, requests] of insight.requestsByEntity) {
474+
if (entity === insight.firstPartyEntity || (filterByThirdParty && entity.name !== filterByThirdParty)) {
475+
continue;
476+
}
477+
478+
for (const request of requests) {
479+
if (filterByTimestamp && request.ts > filterByTimestamp) {
480+
continue;
481+
}
482+
483+
// The overlay entry can be used to highlight any trace entry, including network track entries.
484+
// This function is extracted from the ThirdParties overlay component, since it is not accessible
485+
// from outside the component.
486+
overlays.push({
487+
type: 'ENTRY_OUTLINE',
488+
entry: request,
489+
outlineReason: 'INFO',
490+
});
491+
}
492+
}
493+
494+
return overlays;
495+
},
496+
});
497+
});
498+
499+
// @ts-expect-error
500+
document.getElementById('-blink-dev-tools')?.addEventListener(HighlightEntriesEvent.eventName, (event: HighlightEntriesEvent) => {
501+
const {navigationId, entries} = event.detail;
502+
this.#setActiveInsight({
503+
name: 'highlight-entries',
504+
navigationId,
505+
createOverlayFn: () => {
506+
507+
const overlays: Overlays.Overlays.TimelineOverlay[] = [];
508+
for (const entry of entries) {
509+
510+
// The overlay entry can be used to highlight any trace entry, including network track entries.
511+
// This function is extracted from the ThirdParties overlay component, since it is not accessible
512+
// from outside the component.
513+
overlays.push({
514+
type: 'ENTRY_OUTLINE',
515+
entry: entry.entry,
516+
outlineReason: 'INFO',
517+
});
518+
ModificationsManager.activeManager()?.createAnnotation(entry);
519+
}
520+
521+
return overlays;
522+
},
523+
});
524+
});
525+
526+
// @ts-expect-error
527+
document.getElementById('-blink-dev-tools')?.addEventListener(HighlightLCPImageWithDelayEvent.eventName, (event: HighlightLCPImageWithDelayEvent) => {
528+
const {navigationId, entry} = event.detail;
529+
this.#setActiveInsight({
530+
name: 'highlight-entries',
531+
navigationId,
532+
createOverlayFn: () => {
533+
534+
// Creates an overlay scheme similar to the LCP resource breakdown.
535+
const overlays: Overlays.Overlays.TimelineOverlay[] = [
536+
{
537+
type: 'ENTRY_OUTLINE',
538+
entry: entry.entry,
539+
outlineReason: 'INFO',
540+
},
541+
{
542+
type: 'CANDY_STRIPED_TIME_RANGE',
543+
bounds: TraceEngine.Helpers.Timing.traceWindowFromMicroSeconds(entry.start, entry.end),
544+
entry: entry.entry,
545+
},
546+
{
547+
type: 'TIMESPAN_BREAKDOWN',
548+
sections: [
549+
{
550+
label: 'LCP image request delay',
551+
bounds: TraceEngine.Helpers.Timing.traceWindowFromMicroSeconds(entry.start, entry.end),
552+
showDuration: true,
553+
},
554+
],
555+
entry: entry.entry,
556+
},
557+
{
558+
type: 'TIMESPAN_BREAKDOWN',
559+
sections: [
560+
{
561+
label: 'LCP image request',
562+
bounds: TraceEngine.Helpers.Timing.traceWindowFromMicroSeconds(entry.entry.ts, (
563+
entry.entry.ts + (entry.entry.dur || 0) as TraceEngine.Types.Timing.MicroSeconds
564+
)),
565+
showDuration: true,
566+
},
567+
],
568+
entry: entry.entry,
569+
},
570+
];
571+
572+
return overlays;
573+
},
574+
});
575+
});
576+
457577
this.#sideBar.contentElement.addEventListener(TimelineComponents.Sidebar.EventReferenceClick.eventName, event => {
458578
const {metricEvent} = event;
459579
this.flameChart.setSelectionAndReveal(TimelineSelection.fromTraceEvent(metricEvent));
@@ -2256,6 +2376,9 @@ export const enum Events {
22562376
LoadTraceFile = 'loadtracefile',
22572377
TraceLoadingStarted = 'traceloadingstarted',
22582378
ExportTrace = 'exporttrace',
2379+
HighlightEntries = 'highlightentries',
2380+
HighlightLCPImageWithDelay = 'highlightlcpimagewithdelay',
2381+
ShowThirdParties = 'showthirdparties',
22592382
}
22602383

22612384
export type EventTypes = {
@@ -2265,6 +2388,23 @@ export type EventTypes = {
22652388
[Events.LoadTraceFile]: {
22662389
blob: Blob,
22672390
},
2391+
[Events.HighlightLCPImageWithDelay]: {
2392+
navigationId: string,
2393+
entry: {
2394+
entry: TraceEngine.Types.TraceEvents.TraceEventData,
2395+
start: TraceEngine.Types.Timing.MicroSeconds,
2396+
end: TraceEngine.Types.Timing.MicroSeconds,
2397+
},
2398+
},
2399+
[Events.HighlightEntries]: {
2400+
navigationId: string,
2401+
entries: Array<TraceEngine.Types.File.EntryLabelAnnotation>,
2402+
},
2403+
[Events.ShowThirdParties]: {
2404+
navigationId: string,
2405+
filterByThirdParty?: string,
2406+
filterByTimestamp?: number,
2407+
},
22682408
};
22692409

22702410
export class OpenTraceFileEvent extends CustomEvent<Events.OpenTraceFile> {
@@ -2309,6 +2449,30 @@ export class TraceLoadingStarted extends CustomEvent<Events.TraceLoadingStarted>
23092449
}
23102450
}
23112451

2452+
export class HighlightLCPImageWithDelayEvent extends CustomEvent<EventTypes[Events.HighlightLCPImageWithDelay]> {
2453+
static readonly eventName = Events.HighlightLCPImageWithDelay;
2454+
2455+
constructor(options: EventTypes[Events.HighlightLCPImageWithDelay]) {
2456+
super(HighlightLCPImageWithDelayEvent.eventName, { detail: options });
2457+
}
2458+
}
2459+
2460+
export class HighlightEntriesEvent extends CustomEvent<EventTypes[Events.HighlightEntries]> {
2461+
static readonly eventName = Events.HighlightEntries;
2462+
2463+
constructor(options: EventTypes[Events.HighlightEntries]) {
2464+
super(HighlightEntriesEvent.eventName, { detail: options });
2465+
}
2466+
}
2467+
2468+
export class ShowThirdPartiesEvent extends CustomEvent<EventTypes[Events.ShowThirdParties]> {
2469+
static readonly eventName = Events.ShowThirdParties;
2470+
2471+
constructor(options: EventTypes[Events.ShowThirdParties]) {
2472+
super(ShowThirdPartiesEvent.eventName, { detail: options });
2473+
}
2474+
}
2475+
23122476
export class StatusPane extends UI.Widget.VBox {
23132477
private status: HTMLElement;
23142478
private time: Element|undefined;

0 commit comments

Comments
 (0)