-
Notifications
You must be signed in to change notification settings - Fork 9.4k
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
core(lantern): FCP improvements #7513
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
a few clarifying questions, a few actually important :)
} | ||
|
||
/** | ||
* @param {Node} dependencyGraph | ||
* @param {LH.Artifacts.TraceOfTab} traceOfTab | ||
* @param {number} fcpTs |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
some docs would be good. Not at clear from the outside why this is called fcpTs
but lantern-first-meaningful-paint.js
is passing in fmp
, for instance :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
* @param {number} fcpTs | ||
* @param {function(NetworkNode):boolean} networkFilter | ||
* @param {function(CPUNode):boolean=} cpuFilter | ||
* @return {{possiblyRenderBlockingScriptUrls: Set<string>, actuallyRenderBlockingScriptUrls: Set<string>, blockingCpuNodeIds: Set<string>}} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
actually
reads like possibly
blocking nodes really weren't. definitelyRenderBlockingScriptUrls
? :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
haha good point sounds good 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
well, on further reflection definitely
feels a tad too strong :)
we don't know with 100% certainty, but it's the delta between the two is definitelyNotRenderBlocking
, maybe I just return that directly
* @param {Node} graph | ||
* @param {number} fcpTs | ||
* @param {function(NetworkNode):boolean} networkFilter | ||
* @param {function(CPUNode):boolean=} cpuFilter |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
does {(function(CPUNode):boolean)=}
work? =
isn't supposed to be applicable to return types, but with tsc you never know, so it ends up hard to read
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done 👍
* @param {LH.Artifacts.TraceOfTab} traceOfTab | ||
* @param {number} fcpTs | ||
* @param {function(NetworkNode):boolean} blockingScriptFilter | ||
* @param {function(CPUNode):boolean=} cpuNodeFilter |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cpuNodeFilter
does the opposite of what I expected...maybe incorporate block
/blocking
into its name as well?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah this was a bad name, renamed both of them to extraBlockingCpuNodesToIncludeFilter
lighthouse-core/computed/metrics/lantern-first-contentful-paint.js
Outdated
Show resolved
Hide resolved
Yeah this doesn't make sense at all. :) Like.... the script is render blocking so why would chrome do a real contentful paint before the evaluateScript??? That's not really supposed to happen. Can we look closer at what's going on here?
that sounds awesome. |
Oh the thing is it wasn't really render-blocking. It just had a render-blocking priority. Scripts added to the head by other scripts for example aren't render-blocking but will be requested by Chrome with the same priority as render-blocking scripts. We exclude these types of scripts from the optimistic estimate but still include them in the pessimistic one since they're usually important and could have been the script to actually render the content, but aren't necessarily required. This PR now uses the extra bit of information about when the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nice, I like the cleanup!
One big question and a few documentation comments
lighthouse-core/computed/metrics/lantern-first-contentful-paint.js
Outdated
Show resolved
Hide resolved
lighthouse-core/computed/metrics/lantern-first-contentful-paint.js
Outdated
Show resolved
Hide resolved
lighthouse-core/computed/metrics/lantern-first-contentful-paint.js
Outdated
Show resolved
Hide resolved
const firstPaint = cpuNodes.find(node => node.childEvents.some(e => e.name === 'Paint')); | ||
if (firstPaint) blockingCpuNodeIds.add(firstPaint.id); | ||
const firstParse = cpuNodes.find(node => node.childEvents.some(e => e.name === 'ParseHTML')); | ||
if (firstParse) blockingCpuNodeIds.add(firstParse.id); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
are the FCP/FMP results weird (and not worth keeping) if any of these are missing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
theoretically yes, but in practice I've seen some of these be shifted slightly so I wouldn't want to throw it all away
maybe another candidate for #7041 ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe another candidate for #7041 ?
yeah, probably the best thing before we start throwing on it
lighthouse-core/computed/metrics/lantern-first-contentful-paint.js
Outdated
Show resolved
Hide resolved
return node.hasRenderBlockingPriority(); | ||
const url = node.record.url; | ||
// If the URL definitely wasn't render-blocking then we filter it out. | ||
if (definitelyNotRenderBlockingScriptUrls.has(url)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
definitelyNotRenderBlockingScriptUrls
is a little confusing inside of getBlockingCpuData
, but really nice here!
lighthouse-core/computed/metrics/lantern-first-contentful-paint.js
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
|
||
// A script is *definitely not* render blocking if its EvaluateScript task started after filterTimestamp. | ||
// We'll check `cpuNodes` to see if we can find its EvaluateScript. | ||
// If we can't, that means it started after filterTimestamp, and we add it to our set. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah, this is great
@paulirish not sure if you want to take another look before we land |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the comments are crazy valuable, especially for this kind of thing.
thanks.
lg here.
looks like need a new golden lhr and |
dea2ef5
to
227e683
Compare
sorry y'all the fix for rendering blocking smoke is slightly more involved but I think it makes the just one more quick look? :D the good news is we keep goin' up accuracy-wise! 😃 this is the incremental progress on what we already had 💣 💥 🥇 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
still LGTM :)
I think it makes the
definitelyNotRenderBlocking
computation a little clearer too in the process.
agreed!
lighthouse-core/computed/metrics/lantern-first-contentful-paint.js
Outdated
Show resolved
Hide resolved
lighthouse-core/computed/metrics/lantern-first-contentful-paint.js
Outdated
Show resolved
Hide resolved
extraBlockingCpuNodesToIncludeFilter | ||
) { | ||
/** @type {Map<string, CPUNode>} */ | ||
const scriptUrlToNodeMap = new Map(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe a comment about it being a map from script URL to the earliest associated EvaluateScript
CPUNode?
lighthouse-core/computed/metrics/lantern-first-contentful-paint.js
Outdated
Show resolved
Hide resolved
lighthouse-core/computed/metrics/lantern-first-contentful-paint.js
Outdated
Show resolved
Hide resolved
lighthouse-core/computed/metrics/lantern-first-contentful-paint.js
Outdated
Show resolved
Hide resolved
const firstPaint = cpuNodes.find(node => node.childEvents.some(e => e.name === 'Paint')); | ||
if (firstPaint) blockingCpuNodeIds.add(firstPaint.id); | ||
const firstParse = cpuNodes.find(node => node.childEvents.some(e => e.name === 'ParseHTML')); | ||
if (firstParse) blockingCpuNodeIds.add(firstParse.id); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe another candidate for #7041 ?
yeah, probably the best thing before we start throwing on it
lighthouse-core/computed/metrics/lantern-first-contentful-paint.js
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
works for me. excited about this.
We discussed shipping this in v5 (#7752), so we may wait to land it. |
I think we're good to go here now, right? |
We are! let's do it! |
Summary
While doing some investigation into resilient FCP, I noticed a few cases popping up where we could be more accurate.
Specifically:
Impact
Huge boosts to our FCP accuracy!! 🎉 FMP takes a slight hit to be consistent here, but it doesn't move any sites to worse buckets and FCP has a much higher priority/visibility anyway.
This also shrunk the observed variance for the Hulu case from +/- 2000ms to +/-200ms, which is far more tolerable.