Skip to content

Commit 5c35570

Browse files
jackfranklinDevtools-frontend LUCI CQ
authored andcommitted
AI: create common helper for LCP data
This CL adds `frameId` to each insight, this means that we can look up data from the PageLoadMetricsHandler for an insight. This is useful as for any LCP based Insight we can now fetch the LCP information and put it into the prompt for the LLM. Fixed: 401519930 Change-Id: I1d06c07a94e63f393539b2bbab3feeb584c603c8 Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/6336172 Reviewed-by: Alina Varkki <[email protected]> Commit-Queue: Alina Varkki <[email protected]> Auto-Submit: Jack Franklin <[email protected]> Commit-Queue: Jack Franklin <[email protected]>
1 parent a0739fc commit 5c35570

21 files changed

+137
-26
lines changed

front_end/models/trace/handlers/PageLoadMetricsHandler.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,16 @@ import * as Types from '../types/types.js';
2020
import {data as metaHandlerData} from './MetaHandler.js';
2121
import type {HandlerName} from './types.js';
2222

23+
// Small helpers to make the below type easier to read.
24+
type FrameId = string;
25+
type NavigationId = string;
2326
/**
2427
* This represents the metric scores for all navigations, for all frames in a trace.
2528
* Given a frame id, the map points to another map from navigation id to metric scores.
2629
* The metric scores include the event related to the metric as well as the data regarding
2730
* the score itself.
2831
*/
29-
const metricScoresByFrameId =
30-
new Map</* Frame id */ string, Map</* navigation id */ string, Map<MetricName, MetricScore>>>();
32+
const metricScoresByFrameId = new Map<FrameId, Map<NavigationId, Map<MetricName, MetricScore>>>();
3133

3234
/**
3335
* Page load events with no associated duration that happened in the
@@ -447,3 +449,12 @@ export interface MetricScore {
447449
estimated?: boolean;
448450
timing: Types.Timing.Micro;
449451
}
452+
453+
export type LCPMetricScore = MetricScore&{
454+
event: Types.Events.LargestContentfulPaintCandidate,
455+
metricName: MetricName.LCP,
456+
};
457+
458+
export function metricIsLCP(metric: MetricScore): metric is LCPMetricScore {
459+
return metric.metricName === MetricName.LCP;
460+
}

front_end/models/trace/insights/CLSCulprits.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -582,6 +582,7 @@ export function generateInsight(
582582
}
583583

584584
return finalize({
585+
frameId: context.frameId,
585586
relatedEvents,
586587
animationFailures,
587588
shifts: rootCausesByShift,

front_end/models/trace/insights/DOMSize.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ export function generateInsight(
165165
}
166166

167167
return finalize({
168+
frameId: context.frameId,
168169
largeLayoutUpdates,
169170
largeStyleRecalcs,
170171
maxDOMStats,

front_end/models/trace/insights/DocumentLatency.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -181,13 +181,13 @@ function finalize(partialModel: PartialInsightModel<DocumentLatencyInsightModel>
181181
export function generateInsight(
182182
parsedTrace: Handlers.Types.ParsedTrace, context: InsightSetContext): DocumentLatencyInsightModel {
183183
if (!context.navigation) {
184-
return finalize({});
184+
return finalize({frameId: context.frameId});
185185
}
186186

187187
const documentRequest =
188188
parsedTrace.NetworkRequests.byTime.find(req => req.args.data.requestId === context.navigationId);
189189
if (!documentRequest) {
190-
return finalize({warnings: [InsightWarning.NO_DOCUMENT_REQUEST]});
190+
return finalize({frameId: context.frameId, warnings: [InsightWarning.NO_DOCUMENT_REQUEST]});
191191
}
192192

193193
const serverResponseTime = getServerResponseTime(documentRequest);
@@ -217,6 +217,7 @@ export function generateInsight(
217217
const usesCompression = uncompressedResponseBytes === 0;
218218

219219
return finalize({
220+
frameId: context.frameId,
220221
relatedEvents: [documentRequest],
221222
data: {
222223
serverResponseTime,

front_end/models/trace/insights/DuplicateJavaScript.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,5 +65,5 @@ export function generateInsight(
6565
});
6666

6767
const duplication = Extras.ScriptDuplication.computeScriptDuplication({scripts});
68-
return finalize({duplication});
68+
return finalize({frameId: context.frameId, duplication});
6969
}

front_end/models/trace/insights/FontDisplay.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ export function generateInsight(
100100
const savings = Math.max(...fonts.map(f => f.wastedTime)) as Types.Timing.Milli;
101101

102102
return finalize({
103+
frameId: context.frameId,
103104
relatedEvents: fonts.map(f => f.request),
104105
fonts,
105106
metricSavings: {FCP: savings},

front_end/models/trace/insights/ForcedReflow.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {
1515
InsightCategory,
1616
InsightKeys,
1717
type InsightModel,
18+
type InsightSetContext,
1819
type PartialInsightModel,
1920
} from './types.js';
2021

@@ -199,7 +200,8 @@ function finalize(partialModel: PartialInsightModel<ForcedReflowInsightModel>):
199200
};
200201
}
201202

202-
export function generateInsight(traceParsedData: Handlers.Types.ParsedTrace): ForcedReflowInsightModel {
203+
export function generateInsight(
204+
traceParsedData: Handlers.Types.ParsedTrace, context: InsightSetContext): ForcedReflowInsightModel {
203205
const warningsData = traceParsedData.Warnings;
204206
const entryToNodeMap = traceParsedData.Renderer.entryToNode;
205207

@@ -215,6 +217,7 @@ export function generateInsight(traceParsedData: Handlers.Types.ParsedTrace): Fo
215217
aggregateForcedReflow(warningsData.perWarning, entryToNodeMap);
216218

217219
return finalize({
220+
frameId: context.frameId,
218221
relatedEvents: topLevelFunctionCallData?.topLevelFunctionCallEvents,
219222
topLevelFunctionCallData,
220223
aggregatedBottomUpData,

front_end/models/trace/insights/ImageDelivery.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,7 @@ export function generateInsight(
309309
});
310310

311311
return finalize({
312+
frameId: context.frameId,
312313
optimizableImages,
313314
totalByteSavings: optimizableImages.reduce((total, img) => total + img.byteSavings, 0),
314315
metricSavings: metricSavingsForWastedBytes(wastedBytesByRequestId, context),

front_end/models/trace/insights/InteractionToNextPaint.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,10 @@ export function generateInsight(parsedTrace: Handlers.Types.ParsedTrace, context
8080

8181
if (!interactionEvents.length) {
8282
// A valid result, when there is no user interaction.
83-
return finalize({});
83+
return finalize({
84+
85+
frameId: context.frameId,
86+
});
8487
}
8588

8689
const longestByInteractionId = new Map<number, SyntheticInteractionPair>();
@@ -101,6 +104,7 @@ export function generateInsight(parsedTrace: Handlers.Types.ParsedTrace, context
101104
const highPercentileIndex = Math.min(9, Math.floor(normalizedInteractionEvents.length / 50));
102105

103106
return finalize({
107+
frameId: context.frameId,
104108
relatedEvents: [normalizedInteractionEvents[0]],
105109
longestInteractionEvent: normalizedInteractionEvents[0],
106110
highPercentileInteractionEvent: normalizedInteractionEvents[highPercentileIndex],

front_end/models/trace/insights/LCPDiscovery.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,10 @@ function finalize(partialModel: PartialInsightModel<LCPDiscoveryInsightModel>):
9696
export function generateInsight(
9797
parsedTrace: Handlers.Types.ParsedTrace, context: InsightSetContext): LCPDiscoveryInsightModel {
9898
if (!context.navigation) {
99-
return finalize({});
99+
return finalize({
100+
101+
frameId: context.frameId,
102+
});
100103
}
101104

102105
const networkRequests = parsedTrace.NetworkRequests;
@@ -113,17 +116,17 @@ export function generateInsight(
113116
const metricScore = navMetrics.get(Handlers.ModelHandlers.PageLoadMetrics.MetricName.LCP);
114117
const lcpEvent = metricScore?.event;
115118
if (!lcpEvent || !Types.Events.isLargestContentfulPaintCandidate(lcpEvent)) {
116-
return finalize({warnings: [InsightWarning.NO_LCP]});
119+
return finalize({frameId: context.frameId, warnings: [InsightWarning.NO_LCP]});
117120
}
118121

119122
const docRequest = networkRequests.byTime.find(req => req.args.data.requestId === context.navigationId);
120123
if (!docRequest) {
121-
return finalize({lcpEvent, warnings: [InsightWarning.NO_DOCUMENT_REQUEST]});
124+
return finalize({frameId: context.frameId, lcpEvent, warnings: [InsightWarning.NO_DOCUMENT_REQUEST]});
122125
}
123126

124127
const lcpRequest = parsedTrace.LargestImagePaint.lcpRequestByNavigation.get(context.navigation);
125128
if (!lcpRequest) {
126-
return finalize({lcpEvent});
129+
return finalize({frameId: context.frameId, lcpEvent});
127130
}
128131

129132
const initiatorUrl = lcpRequest.args.data.initiator?.url;
@@ -144,6 +147,7 @@ export function generateInsight(
144147
const priorityHintFound = imageFetchPriorityHint === 'high';
145148

146149
return finalize({
150+
frameId: context.frameId,
147151
lcpEvent,
148152
lcpRequest,
149153
earliestDiscoveryTimeTs: earliestDiscoveryTime ? Types.Timing.Micro(earliestDiscoveryTime) : undefined,

0 commit comments

Comments
 (0)