Skip to content

core(metrics): support LCP in all frames for devtools throttling#11701

Merged
adamraine merged 11 commits into
masterfrom
lcp-all-frames-metrics
Nov 26, 2020
Merged

core(metrics): support LCP in all frames for devtools throttling#11701
adamraine merged 11 commits into
masterfrom
lcp-all-frames-metrics

Conversation

@adamraine

Copy link
Copy Markdown
Contributor

Part 1a of the Framehole implementation plan for LCP events.

@adamraine adamraine requested a review from a team as a code owner November 23, 2020 21:46
@adamraine adamraine requested review from connorjclark and removed request for a team November 23, 2020 21:46
@google-cla google-cla Bot added the cla: yes label Nov 23, 2020
Comment thread lighthouse-core/test/computed/metrics/timing-summary-test.js

@patrickhulce patrickhulce left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks @adamraine :)

Comment thread lighthouse-core/computed/metrics/largest-contentful-paint-all-frames.js Outdated
Comment thread lighthouse-core/computed/metrics/timing-summary.js Outdated
Comment thread lighthouse-core/test/computed/metrics/timing-summary-test.js
Comment thread lighthouse-core/test/lib/tracehouse/trace-processor-test.js
@adamraine

Copy link
Copy Markdown
Contributor Author

@patrickhulce @connorjclark Just a heads up, I'm gonna bring up another PR to merge into this one which supports CLS from all frames.

@connorjclark

connorjclark commented Nov 25, 2020

Copy link
Copy Markdown
Collaborator

can we keep that as a separate PR (and not merge into this branch)?

@adamraine

Copy link
Copy Markdown
Contributor Author

can we keep that as a separate PR (and not merge into this branch)?

Sure

@connorjclark connorjclark left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Patrick, wdyt?

Comment thread lighthouse-core/lib/tracehouse/trace-processor.js Outdated
@@ -0,0 +1,55 @@
[

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

muuuuuch better :) thanks!

Co-authored-by: Patrick Hulce <patrick.hulce@gmail.com>
@adamraine

Copy link
Copy Markdown
Contributor Author

@patrickhulce @connorjclark Do we need to wait for v7 to merge this?

@patrickhulce

Copy link
Copy Markdown
Collaborator

I think the opposite @adamraine we really want to get this in for the last 6.x

@adamraine adamraine merged commit bca4e21 into master Nov 26, 2020
@adamraine adamraine deleted the lcp-all-frames-metrics branch November 26, 2020 01:26

@paulirish paulirish left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

noticed a few things that might matter to the calculation accuracy under certain conditions. @adamraine lemme know if you've already spotted this stuff.

const lcpAllFramesEvt = this.computeValidLCP({
candidateEventName: 'NavStartToLargestContentfulPaint::Candidate::AllFrames::UKM',
invalidateEventName: 'NavStartToLargestContentfulPaint::Invalidate::AllFrames::UKM',
events: keyEvents,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there's an edge case this may not account for.

The situation would be theverge loading in one tab while nytimes is loading in another tab. keyEvents is for all processes and so I think the resulting LCP-AF would merge together both tabs.

I'm not sure this is the case, but it looks like it...

the trace event lives in browser/ so my guess is it's emitted on the browser process. it does contain a mainframeid however. and we have findMainFrameIds, so I think we can filter the trace events to be just the mainframeid ones we care about.

@patrickhulce patrickhulce Nov 30, 2020

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The situation would be theverge loading in one tab while nytimes is loading in another tab. keyEvents is for all processes and so I think the resulting LCP-AF would merge together both tabs.

I jumped to this as well, but I tried on half a dozen pages unsuccessfully 😅 Is the "looks like it" from looking at the code in Chromium or a case that you observed?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What would a trace like this look like?

Using the performance panel, I am able to produce a trace with LCP-AF events with two different values for main_frame_tree_node_id.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm i just got one.

trace: https://gist.github.com/paulirish/ebfeeac8d2a243042041ab4e1bc87c7f

image

repro:

  • chrome-debug
  • open devtools
  • open another chrome window, and make sure both windows are visible (not occluding the other)
  • put example.com in window 1's omnibox and paulirish.com in window 2's.
  • start perf panel recording
  • hit enter on both omniboxes
  • wait a bit and stop recording

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and make sure both windows are visible (not occluding the other)

🤦 this is almost definitely what I forgot

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@paulirish findMainFrameIds doesn't return a node id, is there another way to get the main frame node id?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@paulirish findMainFrameIds doesn't return a node id, is there another way to get the main frame node id?

good question.... doing this would certainly be easier if main_frame_tree_node_id was instead main_frame_tree_frame_id but alas. Hmmmm.. we'll have to do some hunting.

@npm1 do you currently make use of main_frame_tree_frame_id to filter things? as of now, we don't have any mapping between frames/frametrees to node ids, so before we invent one, I'm curious if something already exists.

firstContentfulPaint: frameTimings.timings.firstContentfulPaint,
firstMeaningfulPaint: frameTimings.timings.firstMeaningfulPaint,
largestContentfulPaint: frameTimings.timings.largestContentfulPaint,
largestContentfulPaintAllFrames: maybeGetTiming(lcpAllFramesEvt && lcpAllFramesEvt.ts),

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

something i spotted while looking at the trace event.....

https://source.chromium.org/chromium/chromium/src/+/master:chrome/browser/page_load_metrics/observers/core/ukm_page_load_metrics_observer.cc;l=1091-1095;drc=2b934611e4e480b7121488288f97ef27e0950e2a

It seems like sometimes the trace event carries a specific timestamp.. so i think we'd want to use that rather than the event's ts.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't seem to find the timestamp you're referring to. There is only a durationInMilliseconds property.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

my silly project agrees with @adamraine https://github.com/connorjclark/chrome-trace-events-tsc/blob/master/dist/lh-trace-events.d.ts#L487 (altho I only used one recent trace from cnn.com)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@connorjclark thanks for checking. yeah you can see in the .cc source i linked that there are two ways the LCP trace event are emitted. I haven't really tracked back the conditions that determine which of the two are used.. but.. we'd need enough traces to get both of em for yr project to catch it, i guess. no big deal though.

@adamraine ah yeah.. actually the durationInMilliseconds prop is exactly what i was talking about. (I hadn't clicked through on DataAsTraceValue() till now).

But yes it looks vaguely like: if durationInMilliseconds is being provided, it should be used rather than the ts of the event. @npm1 is that what's going on?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if durationInMilliseconds is being provided, it should be used rather than the ts of the event.

👀 at our time origin complexities, oh boy 😅

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct, durationInMilliseconds is the LCP value. Sorry for the confusion, maybe there was a way to have the trace event's timestamp be the LCP itself? It's probably a bit late to fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants