77 * and exports them in the shape of a map with the following shape:
88 * Map(FrameId -> Map(navigationID -> metrics) )
99 *
10+ * It also includes soft navigations as separate "navigations", though since soft
11+ * navs use different events, the "navigationID" for them is created in this handler.
12+ *
1013 * It also exports all markers in a trace in an array.
1114 *
1215 * Some metrics are taken directly from a page load events (AKA markers) like DCL.
@@ -22,8 +25,9 @@ import type {HandlerName} from './types.js';
2225
2326// Small helpers to make the below type easier to read.
2427type FrameId = string ;
25- type NavigationId = string ;
28+ type NavigationId = string | `softnav-${ string } ` ;
2629type AnyNavigationStart = Types . Events . NavigationStart | Types . Events . SoftNavigationStart ;
30+
2731/**
2832 * This represents the metric scores for all navigations, for all frames in a trace.
2933 * Given a frame id, the map points to another map from navigation id to metric scores.
@@ -55,7 +59,7 @@ let pageLoadEventsArray: Types.Events.PageLoadEvent[] = [];
5559// trace, we store that and delete the prior event. When we've parsed the
5660// entire trace this set will contain all the LCP events that were used - e.g.
5761// the candidates that were the actual LCP events.
58- let selectedLCPCandidateEvents = new Set < Types . Events . LargestContentfulPaintCandidate > ( ) ;
62+ let selectedLCPCandidateEvents = new Set < Types . Events . AnyLargestContentfulPaintCandidate > ( ) ;
5963
6064export function handleEvent ( event : Types . Events . Event ) : void {
6165 if ( ! Types . Events . eventIsPageLoadEvent ( event ) ) {
@@ -159,7 +163,7 @@ function storePageLoadMetricAgainstNavigationId(
159163 return ;
160164 }
161165
162- if ( Types . Events . isLargestContentfulPaintCandidate ( event ) ) {
166+ if ( Types . Events . isAnyLargestContentfulPaintCandidate ( event ) ) {
163167 const candidateIndex = event . args . data ?. candidateIndex ;
164168 if ( ! candidateIndex ) {
165169 throw new Error ( 'Largest Contentful Paint unexpectedly had no candidateIndex.' ) ;
@@ -182,7 +186,7 @@ function storePageLoadMetricAgainstNavigationId(
182186 }
183187 const lastLCPCandidateEvent = lastLCPCandidate . event ;
184188
185- if ( ! Types . Events . isLargestContentfulPaintCandidate ( lastLCPCandidateEvent ) ) {
189+ if ( ! Types . Events . isAnyLargestContentfulPaintCandidate ( lastLCPCandidateEvent ) ) {
186190 return ;
187191 }
188192 const lastCandidateIndex = lastLCPCandidateEvent . args . data ?. candidateIndex ;
@@ -220,7 +224,7 @@ function storeMetricScore(frameId: string, navigationId: string, metricScore: Me
220224
221225export function getFrameIdForPageLoadEvent ( event : Types . Events . PageLoadEvent ) : string {
222226 if ( Types . Events . isFirstContentfulPaint ( event ) || Types . Events . isInteractiveTime ( event ) ||
223- Types . Events . isLargestContentfulPaintCandidate ( event ) || Types . Events . isNavigationStart ( event ) ||
227+ Types . Events . isAnyLargestContentfulPaintCandidate ( event ) || Types . Events . isNavigationStart ( event ) ||
224228 Types . Events . isSoftNavigationStart ( event ) || Types . Events . isLayoutShift ( event ) ||
225229 Types . Events . isFirstPaint ( event ) ) {
226230 return event . args . frame ;
@@ -236,15 +240,22 @@ export function getFrameIdForPageLoadEvent(event: Types.Events.PageLoadEvent): s
236240}
237241
238242function getNavigationForPageLoadEvent ( event : Types . Events . PageLoadEvent ) : AnyNavigationStart | null {
239- if ( Types . Events . isFirstContentfulPaint ( event ) || Types . Events . isLargestContentfulPaintCandidate ( event ) ||
243+ if ( Types . Events . isFirstContentfulPaint ( event ) || Types . Events . isAnyLargestContentfulPaintCandidate ( event ) ||
240244 Types . Events . isFirstPaint ( event ) ) {
241- const navigationId = event . args . data ?. navigationId ;
242- if ( ! navigationId ) {
243- throw new Error ( 'Trace event unexpectedly had no navigation ID.' ) ;
245+ const { navigationsByNavigationId, softNavigationsById} = metaHandlerData ( ) ;
246+ let navigation ;
247+ if ( event . name === Types . Events . Name . MARK_LCP_CANDIDATE_FOR_SOFT_NAVIGATION &&
248+ event . args . data ?. performanceTimelineNavigationId ) {
249+ navigation = softNavigationsById . get ( event . args . data . performanceTimelineNavigationId ) ;
244250 }
245- const { navigationsByNavigationId} = metaHandlerData ( ) ;
246- const navigation = navigationsByNavigationId . get ( navigationId ) ;
251+ if ( ! navigation ) {
252+ const navigationId = event . args . data ?. navigationId ;
253+ if ( ! navigationId ) {
254+ throw new Error ( 'Trace event unexpectedly had no navigation ID.' ) ;
255+ }
247256
257+ navigation = navigationsByNavigationId . get ( navigationId ) ;
258+ }
248259 if ( ! navigation ) {
249260 // This event's navigation has been filtered out by the meta handler as a noise event.
250261 return null ;
@@ -390,7 +401,8 @@ export async function finalize(): Promise<void> {
390401 const allFinalLCPEvents = gatherFinalLCPEvents ( ) ;
391402 const mainFrame = metaHandlerData ( ) . mainFrameId ;
392403 // Filter out LCP candidates to use only definitive LCP values
393- const allEventsButLCP = pageLoadEventsArray . filter ( event => ! Types . Events . isLargestContentfulPaintCandidate ( event ) ) ;
404+ const allEventsButLCP =
405+ pageLoadEventsArray . filter ( event => ! Types . Events . isAnyLargestContentfulPaintCandidate ( event ) ) ;
394406 const markerEvents = [ ...allFinalLCPEvents , ...allEventsButLCP ] . filter ( Types . Events . isMarkerEvent ) ;
395407 // Filter by main frame and sort.
396408 allMarkerEvents =
@@ -403,8 +415,10 @@ export interface PageLoadMetricsData {
403415 * Given a frame id, the map points to another map from navigation id to metric scores.
404416 * The metric scores include the event related to the metric as well as the data regarding
405417 * the score itself.
418+ *
419+ * Soft navigations have a faked NavigationId that starts with `softnav-`.
406420 */
407- metricScoresByFrameId : Map < string , Map < string , Map < MetricName , MetricScore > > > ;
421+ metricScoresByFrameId : Map < string , Map < NavigationId , Map < MetricName , MetricScore > > > ;
408422 /**
409423 * Page load events with no associated duration that happened in the
410424 * main frame.
0 commit comments