-
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(image-elements): set 5s time budget, add _privateCssSizing #12065
Changes from 3 commits
f6f8069
7c6f6ea
f94f851
a6b5ec2
b07eb63
6e00733
6908ee2
449f39b
689c1c1
8e411dd
0fbc7d4
6bfb5ea
37663b4
9bc2c89
fea8885
dc7f4a0
b80096c
7d80b31
99b3d4a
8503001
7e26ae2
b19a8d3
3a5eea3
df4eb47
36b31f3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -249,6 +249,10 @@ class ImageElements extends Gatherer { | |||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
/** | ||||||||||||||||||||||||||||
* Images might be sized via CSS. In order to compute unsized-images failures, we need to collect | ||||||||||||||||||||||||||||
* matched CSS rules to see if this is the case. | ||||||||||||||||||||||||||||
* Perf warning: Running this for 700 elements takes 1s to 5s. | ||||||||||||||||||||||||||||
* @url http://go/dwoqq (googlers only) | ||||||||||||||||||||||||||||
* @param {Driver} driver | ||||||||||||||||||||||||||||
* @param {string} devtoolsNodePath | ||||||||||||||||||||||||||||
* @param {LH.Artifacts.ImageElement} element | ||||||||||||||||||||||||||||
|
@@ -308,30 +312,39 @@ class ImageElements extends Gatherer { | |||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
/** @type {Array<LH.Artifacts.ImageElement>} */ | ||||||||||||||||||||||||||||
const imageUsage = []; | ||||||||||||||||||||||||||||
const top50Images = Object.values(indexedNetworkRecords) | ||||||||||||||||||||||||||||
.sort((a, b) => b.resourceSize - a.resourceSize) | ||||||||||||||||||||||||||||
.slice(0, 50); | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
await Promise.all([ | ||||||||||||||||||||||||||||
driver.sendCommand('DOM.enable'), | ||||||||||||||||||||||||||||
driver.sendCommand('CSS.enable'), | ||||||||||||||||||||||||||||
driver.sendCommand('DOM.getDocument', {depth: -1, pierce: true}), | ||||||||||||||||||||||||||||
]); | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
// Sort (in-place) as largest images descending | ||||||||||||||||||||||||||||
elements.sort((a, b) => { | ||||||||||||||||||||||||||||
const aRecord = indexedNetworkRecords[a.src] || {}; | ||||||||||||||||||||||||||||
const bRecord = indexedNetworkRecords[b.src] || {}; | ||||||||||||||||||||||||||||
return bRecord.resourceSize - aRecord.resourceSize; | ||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
// Don't allow more than 3s of this expensive protocol work | ||||||||||||||||||||||||||||
paulirish marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||
let hasBudget = true; | ||||||||||||||||||||||||||||
paulirish marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||
setTimeout(_ => (hasBudget = false), 3000); | ||||||||||||||||||||||||||||
connorjclark marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
for (let element of elements) { | ||||||||||||||||||||||||||||
// Pull some of our information directly off the network record. | ||||||||||||||||||||||||||||
paulirish marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||
const networkRecord = indexedNetworkRecords[element.src] || {}; | ||||||||||||||||||||||||||||
element.mimeType = networkRecord.mimeType; | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
if (!element.isInShadowDOM && !element.isCss) { | ||||||||||||||||||||||||||||
// Need source rules to determine if sized via CSS (for unsized-images). | ||||||||||||||||||||||||||||
if (!element.isInShadowDOM && !element.isCss && hasBudget) { | ||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Adding this bailout is the big change. Won't this lead to false failures? My read of lighthouse/lighthouse-core/audits/unsized-images.js Lines 70 to 82 in aaf1365
is that if There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (also it looks like we don't have any There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh, I did miss this change. The previous PR was just focused on saving time for the second request for the source rules, and that's all I was looking at. So the long tail is not that the 50 largest elements take a long time in
Should we mark these fields There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we discussed in chat.. highlights from that:
👍 👍 👍 👍 👍 👍 idea for
edit: filed in #12077 |
||||||||||||||||||||||||||||
await this.fetchSourceRules(driver, element.node.devtoolsNodePath, element); | ||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||
// Images within `picture` behave strangely and natural size information isn't accurate, | ||||||||||||||||||||||||||||
// CSS images have no natural size information at all. Try to get the actual size if we can. | ||||||||||||||||||||||||||||
// Additional fetch is expensive; don't bother if we don't have a networkRecord for the image, | ||||||||||||||||||||||||||||
// or it's not in the top 50 largest images. | ||||||||||||||||||||||||||||
// Additional fetch is expensive; don't bother if we don't have a networkRecord for the image. | ||||||||||||||||||||||||||||
if ( | ||||||||||||||||||||||||||||
(element.isPicture || element.isCss || element.srcset) && | ||||||||||||||||||||||||||||
top50Images.includes(networkRecord) | ||||||||||||||||||||||||||||
networkRecord && hasBudget | ||||||||||||||||||||||||||||
) { | ||||||||||||||||||||||||||||
element = await this.fetchElementWithSizeInformation(driver, element); | ||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||
|
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.
Just checking: did you mean 50 elements here (the previous limit)?
I presume that is 3s for the top 50, so it is surprising that 700 would only take 1-5s.
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 thx for bringing attention to these numbers.
nah i was just trying to provide some general context. though TBH the count of total imageElements doesn't correlate too well. kohls has 700 and takes 1s on my machine and 5s on LR... however like 500 of them are data uris and 495 of those are reusing network resources.
but the gatherer cost correlates with # of network-resource-associated non-css non-shadowdom images that we do these protocol calls for. (something like ~160 for kohls i think? eh.)
I'll remove this particular sentence and replace it with something more useful.
this 3s 85th percentile figure is accurate for staging LR, which has the top50 filter for fetchElementWithSizeInformation but not for fetchSourceRules.
700 does sound like a lot, but language selectors w/ flag sprites and other lazyload image stuff, the number can get high pretty quickly. shrug. i couldn't tell you what the distribution of ImageElements.length is for LR, but this investigation does make me curious...