core: implement UKM Invalidate fallback for LCP#16956
Conversation
The new Baseline Compatibility audit introduces a UI string. This updates the allowed collisions array in to prevent CI assertion failures.
9d65964 to
7042aff
Compare
paulirish
left a comment
There was a problem hiding this comment.
as discussed.. I don't love the data signals we have to work with.. it appears our repro cases are missing trace events..
eg our repro trace has 12 NavStartToLargestContentfulPaint::Invalidate::AllFrames::UKM events and zero NavStartToLargestContentfulPaint::Candidate::AllFrames::UKM (and zero NavStartToLargestContentfulPaint::AllFrames::UMA)
and that just doesnt make sense.
but.. as it has no 'largestContentfulPaint::Candidate' (or regular invalidate).. and yet we know it paints and looks good. so yeah very weird.
but yeah this solution is good for now, until we're ready to dig into the lossy trace event emission problems. :)
| pid: lastInvalidate.pid, | ||
| tid: lastInvalidate.tid, | ||
| args: { | ||
| frame: 'main_frame', // Mocked frame ID |
There was a problem hiding this comment.
you can compute this if you want. (right now it seems like you dont have to .. but.. i wouldnt mind trying to set this correctly)
7042aff to
410eefe
Compare
| // If no standard LCP candidate is found, try the UKM AllFramesEvents. | ||
| if (!maxLcpAcrossFrames) { | ||
| const ukmEvents = events.filter( | ||
| (e) => | ||
| e.name.includes('LargestContentfulPaint') && e.name.includes('UKM') | ||
| ); | ||
|
|
||
| // In the rare cases this whole fallback is necessary, the | ||
| // NavStartToLargestContentfulPaint::Candidate::AllFrames::UKM events are missing too. | ||
| // As a result, the only useful signal left is the AllFrames invalidates. | ||
| // Not ideal since they are 1 paint behind, but.. better than the dreaded | ||
| // NO_LCP error | ||
| const targetEventName = | ||
| 'NavStartToLargestContentfulPaint::Invalidate::AllFrames::UKM'; | ||
| const ukmInvalidates = ukmEvents.filter((e) => e.name === targetEventName); | ||
|
|
||
| if (ukmInvalidates.length > 0) { | ||
| ukmInvalidates.sort((a, b) => a.ts - b.ts); | ||
| const lastInvalidate = ukmInvalidates[ukmInvalidates.length - 1]; |
There was a problem hiding this comment.
| // If no standard LCP candidate is found, try the UKM AllFramesEvents. | |
| if (!maxLcpAcrossFrames) { | |
| const ukmEvents = events.filter( | |
| (e) => | |
| e.name.includes('LargestContentfulPaint') && e.name.includes('UKM') | |
| ); | |
| // In the rare cases this whole fallback is necessary, the | |
| // NavStartToLargestContentfulPaint::Candidate::AllFrames::UKM events are missing too. | |
| // As a result, the only useful signal left is the AllFrames invalidates. | |
| // Not ideal since they are 1 paint behind, but.. better than the dreaded | |
| // NO_LCP error | |
| const targetEventName = | |
| 'NavStartToLargestContentfulPaint::Invalidate::AllFrames::UKM'; | |
| const ukmInvalidates = ukmEvents.filter((e) => e.name === targetEventName); | |
| if (ukmInvalidates.length > 0) { | |
| ukmInvalidates.sort((a, b) => a.ts - b.ts); | |
| const lastInvalidate = ukmInvalidates[ukmInvalidates.length - 1]; | |
| // If no standard LCP candidate is found, try the UKM AllFramesEvents. | |
| if (!maxLcpAcrossFrames) { | |
| // In the rare cases this whole fallback is necessary, the | |
| // NavStartToLargestContentfulPaint::Candidate::AllFrames::UKM events are missing too. | |
| // As a result, the only useful signal left is the AllFrames invalidates. | |
| // Not ideal since they are 1 paint behind, but.. better than the dreaded | |
| // NO_LCP error | |
| const targetEventName = | |
| 'NavStartToLargestContentfulPaint::Invalidate::AllFrames::UKM'; | |
| const ukmInvalidates = events.filter(e => e.name === targetEventName); | |
| if (ukmInvalidates.length > 0) { | |
| const lastInvalidate = .sort((a, b) => a.ts - b.ts).at(-1); |
fwiw this isnt just for code golfing sake :)
the
events.filter(e => e.name.includes(x) && e.name.includes(y)) is pretty expensive (traces often have 5M events+ ) and.. we really only care about this singular name, right?
( also fwiw you can just hit 'commit' here and then pull locally. )
If no standard LCP candidates are found in the trace, fall back to using the last UKM Invalidate event as a mock candidate. This prevents NO_LCP errors when standard candidates are missing.