Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce TraceOfTab computed artifact #1549

Merged
merged 7 commits into from
Jan 28, 2017
Merged

Introduce TraceOfTab computed artifact #1549

merged 7 commits into from
Jan 28, 2017

Conversation

paulirish
Copy link
Member

@paulirish paulirish commented Jan 27, 2017

We often need to parse a trace and find the main thread, its navigationStart, and get our thread events available and sorted.

This PR introduces a computed artifact that can be reused across audits. It also migrates FMP, TTI, and user-timing audits to leverage it.

Reviewers: there is some noisiness in the diff that ?w=1 will nuke.

--

should fix #762

// fMP will follow at/after the FCP, though we allow some timestamp tolerance
const firstMeaningfulPaint = frameEvents.find(e =>
const firstMeaningfulPaint = tabTrace.traceEvents.find(e =>
Copy link
Collaborator

Choose a reason for hiding this comment

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

I know this is an FMP audit but seems a little strange that it's missing from the TraceOfTab while FCP is still there. Does FCP never fire twice but FMP does and that's why we have to worry about it here?

Copy link
Member Author

Choose a reason for hiding this comment

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

FCP is super reliable in a trace. I use FCP to select the best navStart and so far that is the most robust method. (if this werent the case, i wouldnt have grabbed FCP there)

FMP is definitely not (and im thinking we should soon write our own FMP selection based on the candidates, as the real one's network idle detection is taking too long. anyway..)

however technically i could do this FMP selection in the computed artifact just so that TTI audit doesn't need to depend on both of the taboftrace artifact and fmp audit at the same time. that's fine with me.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Moving any proper event deduping/finding to one place sounds good to me!


// Get all blink.user_timing events
// The event phases we are interested in are mark and instant events (R, i, I)
// and duration events which correspond to measures (B, b, E, e).
Copy link
Collaborator

Choose a reason for hiding this comment

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

Wow these are really fun names :)

// Mark events fall under phases R and I (or i)
if (ut.ph === 'R' || ut.ph.toUpperCase() === 'I') {
// Add user timings event to array
if (ut.name !== 'navigationStart') {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can't we move this above and simplify a bit?

Copy link
Member Author

Choose a reason for hiding this comment

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

yah definitely. I'll put this in the earlier rejection filter. good call.

@brendankenny
Copy link
Member

love this

@paulirish
Copy link
Member Author

updated. and tests added. ptal

Copy link
Member

@brendankenny brendankenny left a comment

Choose a reason for hiding this comment

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

this is going to be great

@@ -0,0 +1,70 @@
/**
* @license
* Copyright 2016 Google Inc. All rights reserved.
Copy link
Member

Choose a reason for hiding this comment

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

2017 :)

const ComputedArtifact = require('./computed-artifact');
const fMPAudit = require('../../audits/first-meaningful-paint');

class TraceOfTab extends ComputedArtifact {
Copy link
Member

Choose a reason for hiding this comment

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

will you add a fileoverview or class-level doc on what this provides?

const frameEvents = keyEvents.filter(e => e.args.frame === startedInPageEvt.args.data.page);

// Find our first FCP
const firstFCP = frameEvents.find(e => e.name === 'firstContentfulPaint');
Copy link
Member

Choose a reason for hiding this comment

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

so a common cause of current audit failures is not finding the FCP event and throwing on firstFCP.ts, below. Trying it with airhorner now, I regularly get traces with no firstContentfulPaint anywhere in the trace. Is there a backup method for identifying navStart in that instance and a way to handle other calculations based on FCP? Maybe if there's only a single one of them? Or is it possible there's only one but it's still wrong?

Copy link
Member

Choose a reason for hiding this comment

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

for reference, in an example trace, here are the names of the events in frameEvents at this point:
['navigationStart', 'fetchStart', 'responseEnd', 'unloadEventStart', 'unloadEventEnd', 'domLoading', 'firstLayout', 'firstPaint', 'domInteractive', 'domContentLoadedEventStart', 'domContentLoadedEventEnd', 'domComplete', 'loadEventStart', 'loadEventEnd']

Copy link
Member Author

Choose a reason for hiding this comment

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

sounds good. mind if i fix that bug in a followup?
happy to, just want to add proper tests for it

Copy link
Member

Choose a reason for hiding this comment

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

mind if i fix that bug in a followup?

yeah, sounds good

Copy link
Member Author

Choose a reason for hiding this comment

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

filed #1567

// being up to 1ms BEFORE the fCP. We're okay if this happens, however if we see
// a gap of more than 2 frames (32,000 microseconds), then it's a bug that should
// be addressed in FirstMeaningfulPaintDetector.cpp
static get toleranceMs() {
Copy link
Member

Choose a reason for hiding this comment

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

this should live in trace-of-tab.js now

Copy link
Member Author

Choose a reason for hiding this comment

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

k

@@ -0,0 +1,53 @@
/**
* Copyright 2016 Google Inc. All rights reserved.
Copy link
Member

Choose a reason for hiding this comment

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

2017

}).sort((event0, event1) => event0.ts - event1.ts);

return {
traceEvents: allFrameEvents,
Copy link
Member

Choose a reason for hiding this comment

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

maybe something in the property name that these are specifically from the one process?

Copy link
Member Author

Choose a reason for hiding this comment

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

processEvents ? I kind of like having that part kind of transparent, TBH. So i'd rather keep it the standard name for the array, but let me know if you feel strongly

Copy link
Member

Choose a reason for hiding this comment

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

yeah, I get the transparency argument too, but there's also the case of -- I'm writing a gatherer that needs trace events, how do I figure out which events belong to my process? Unless you read the source of this you wouldn't know. Maybe fixable with just some docs, though :)

Copy link
Member Author

Choose a reason for hiding this comment

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

renamed to processEvents. :)

/* eslint-env mocha */
describe('Trace of Tab computed artifact:', () => {
describe('finds correct FMP in various traces', () => {
it('finds the fMP if there was a tracingStartedInPage after the frame\'s navStart', () => {
Copy link
Member

Choose a reason for hiding this comment

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

any other invariants to check? Maybe they all have the same pid?

Copy link
Member Author

Choose a reason for hiding this comment

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

done

// fMP will follow at/after the FCP, though we allow some timestamp tolerance
const firstMeaningfulPaint = frameEvents.find(e =>
e.name === 'firstMeaningfulPaint' && e.ts >= (firstFCP.ts - FCPFMP_TOLERANCE));
static collectEvents(tabTrace) {
Copy link
Member

Choose a reason for hiding this comment

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

having a function for this is kind of overkill now. Inline in either audit or calculateScore, maybe?

Copy link
Member Author

Choose a reason for hiding this comment

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

true! but #1564 will make it more valuable.

Copy link
Member Author

Choose a reason for hiding this comment

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

done

@paulirish
Copy link
Member Author

ptal

Copy link
Member

@brendankenny brendankenny left a comment

Choose a reason for hiding this comment

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

LGTM! ✏️ 📑

@brendankenny brendankenny merged commit 7a3dbbd into master Jan 28, 2017
@brendankenny brendankenny deleted the trace-of-tab branch January 28, 2017 02:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

User timing marks show negative numbers (1.1.5)
3 participants