core(image-elements): set 5s time budget, add _privateCssSizing#12065
Conversation
| /** | ||
| * 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. |
There was a problem hiding this comment.
Just checking: did you mean 50 elements here (the previous limit)?
3s is currently the ~85th percentile on LR staging.
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.
yeah thx for bringing attention to these numbers.
Just checking: did you mean 50 elements here (the previous limit)?
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.
3s is currently the ~85th percentile on LR staging.
I presume that is 3s for the top 50, so it is surprising that 700 would only take 1-5s.
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...
|
|
||
| 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.
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 fetchSourceRules isn't run, then cssWidth and cssHeight will be undefined, and so images could be falsely marked as unsized. We should probably fail the other way, not making a claim if we don't have the info?
There was a problem hiding this comment.
(also it looks like we don't have any unsized-image tests with cssWidth: undefined, cssHeight: undefined. Not a huge deal because we rely on falsy behavior so the tests using the empty string are equivalent, but we should probably add a few at some point since that's an allowed state)
There was a problem hiding this comment.
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 fetchElementWithSizeInformation , but that all the elements take a long time to go thru fetchSourceRules
We should probably fail the other way, not making a claim if we don't have the info?
Should we mark these fields null to signify we don't know, and undefined if the element size is not specified (aka when getEffectiveSizingRule returns undefined)? Or put cssWidth/cssHeight into an optional property cssSizing?: {width?: string, height?: string}?
There was a problem hiding this comment.
we discussed in chat.. highlights from that:
I tend to think of
undefinedas equivalent to "not set" andnullas equivalent to "set and has no value".
👍 👍 👍 👍 👍 👍
idea for imageElement.cssSizing obj width width/height props.. obj is appropriately null/undefined if skipped etc.
obj could include the naturalWidth bits as well and be fetchedDimensions or we keep 'em separate.
it would be nice on the next major to do a minor rethink of ImageElements to make it easier on audits using them, since naturalWidth/naturalHeight is in a similar but not quite the same situation as cssWidth/cssHeight after this change
(to add to the null/undefined confusion, don't forget the return value of el.getAttribute('notASetAttribute') :)
edit: filed in #12077
Co-authored-by: Connor Clark <cjamcl@google.com>
…ndefined. but anyway now its explicitly null. yay
+1. Seems like a good eng sync topic given that we all seem to be on ever so slightly different pages :) Not smoke testing this doesn't feel good, but I have no suggestions for a good way to test it :/ |
Co-authored-by: Connor Clark <cjamcl@google.com>
2ec71e0 to
7d80b31
Compare
works for me. renamed to |
| /** The CSS width property of the image element. */ | ||
| /** | ||
| * The CSS width property of the image element. | ||
| * @deprecated Use `element?._privateCssSizing.width` instead. |
There was a problem hiding this comment.
should these deprecations be TODO since we don't actually want anyone using _privateCssSizing yet?
| cssHeight?: string; | ||
| /** | ||
| * The width/height of the element as defined by matching CSS rules. Set to `undefined` if the data was not collected. | ||
| * @private |
There was a problem hiding this comment.
seems not worth it to ts-expect-error all uses of this to keep it @private? We could actually mark this @deprecated which is kind of backwards but would discourage use and strike it out in vscode but still leave it visible for type checking. Maybe there are other options?
There was a problem hiding this comment.
i dig it. done. and added some careful wording around it.
Co-authored-by: Brendan Kenny <bckenny@gmail.com>
as explored in #11289, we can spend a lot of time in image-elements gathering on some pages.
https://www.kohls.comis one such repro.this PR adds a time budget the expensive parts of gathering that data.
3s is currently the ~85th percentile on LR staging.
fix #11289
also related: #12054