-
Notifications
You must be signed in to change notification settings - Fork 211
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
Correctly handle image types when preloading LCP images #6638
Comments
@piotrbak I have some points to clarify:
|
@jeawhanlee We're assuming that the first source is the most optimised one. For the media attributes we're leaving it like it is. @DahmaniAdame Do you think it's possible to have that kind of complicated picture structure that would contain both, different types declarations and different media queries? |
It's a possibility. The media attribute in |
@piotrbak @DahmaniAdame just to be clear here, Are we only preloading the first source element when there is a combination similar to AVIF/WEBP/REGULAR or we are preloading the first source element regardless of the image type but with exception to source element with media attributes? |
@jeawhanlee @piotrbak it needs to be the first Let's assume WEBP |
@DahmaniAdame @jeawhanlee But here we're talking about the |
Reproduce the problem ✅I did not reproduce but I can see it in the sample templates in the issue here Identify the root cause ✅We are preloading every source in the picture element here Scope a solution ✅
Update tests. Estimate the effort ✅[S] |
What I got from @piotrbak, This enhancement will not be applied if the |
I think this is correct, we don't want to mess with other possible conditions. |
LGTM |
@piotrbak I have just seen Google report that the image being served with the new LCP function is a jpeg file. It makes my pagespeed results way lower on mobile. Will this fix it? I use imagify to create Webp versions of all. |
@bwafels yes, it should :) |
@DahmaniAdame Ah good news. That means I do not need to make a new bug report :D. I did see that for my mobile version of the site the LCP does not seem to work but I send a message to support to check it out. |
@bwafels just had a look at the site you shared on the ticket. |
Moving back to Needs Grooming and adding product direction tag following this discussion: https://wp-media.slack.com/archives/CUT7FLHF1/p1716458584865109?thread_ts=1716418401.922879&cid=CUT7FLHF1 |
Reproduce the problem ✅I did reproduce the problem, Identify the root cause ✅There is a lot to say actually.
Then about preloading the first And finally for the second case scenario in the initial message of the issue, we aren't getting the Scope a solution ✅For the first 2 issues mentioned in the previous part, we need to modify the potential candidates part of the const topCandidates = potentialCandidates.map(element => {
// Skip if the element is an img and its parent is a picture.
if ('img' === element.nodeName.toLowerCase() && 'picture' === element.parentElement.nodeName.toLowerCase() ) {
return null;
}
let rect;
if ('picture' === element.nodeName.toLowerCase()) {
const imgElement = element.querySelector('img');
if (imgElement) {
rect = imgElement.getBoundingClientRect();
} else {
return null;
}
} else {
rect = element.getBoundingClientRect();
}
return {
element: element,
rect: rect,
};
})
.filter(item => item !== null) // Filter out null values here.
.filter(item => {
return (
item.rect.width > 0 &&
item.rect.height > 0 &&
this._isIntersecting(item.rect)
);
})
.map(item => ({
item,
area: this._getElementArea(item.rect),
elementInfo: this._getElementInfo(item.element),
}))
.sort((a, b) => b.area - a.area)
.slice(0, count); In order to preload the first element_info.sources = Array.from(element.querySelectorAll('source')).map(source => ({
srcset: source.srcset || '',
media: source.media || '',
type: source.type || ''
})); Then in the Controller, we need to adapt the function
// Check if the media attribute is empty and the type attribute is not.
if ( empty($media) && !empty($source->type) ) {
// Generate the link tag.
$tag .= $start_tag . 'href="' . $source->srcset . '"' . $end_tag;
break;
} else {
// Append the source and media query to the tag string.
$tag .= $start_tag . 'href="' . $source->srcset . '" media="' . $media . '"' . $end_tag;
} This will make sure that we only preload the first Finally, about the second case scenario, we need to add element_info.sources = Array.from(element.querySelectorAll('source')).map(source => ({
srcset: source.srcset || '',
media: source.media || '',
type: source.type || ''
})); to element_info.sources = Array.from(element.querySelectorAll('source')).map(source => ({
srcset: source.srcset || '',
media: source.media || '',
type: source.type || '',
sizes: source.sizes || ''
})); And finally in the Controller::generate_source_tags, we need to add in the loop if ( ! empty( $source->sizes ) ) {
$sizes = 'imagesizes="'.$source->sizes.'"';
}
// Check if the media attribute is empty and the type attribute is not.
if ( empty($media) && !empty($source->type) ) {
// Generate the link tag.
$tag .= $start_tag . 'href="' . $source->srcset . '" ' . ($sizes ?? '') . $end_tag ;
break;
} else {
// Append the source and media query to the tag string.
$tag .= $start_tag . 'href="' . $source->srcset . '" media="' . $media . '" '. ($sizes ?? '') . $end_tag;
// If a max-width is found in the source's media attribute, update the previous max-width.
if ( preg_match( '/\(max-width: (\d+(\.\d+)?)px\)/', $source->media, $matches ) ) {
$prev_max_width = floatval( $matches[1] );
}
} This will ensure that the tag gets the attribute Finally we need to Update tests. Estimate the effort ✅[M] |
Dismiss. I got tests confused 😅 My bad 🙏
Should translate to:
|
To sum up everything. The only change that's needed is to make sure that: becomes: Acceptance criteria:
The last two points are here to remind that we're still working only on the preload with different image |
@MathieuLamiot @Miraeld Should it go back to the grooming or the change can be implemented without it? |
I think can be without it, I will check it tomorrow with clear head. |
Before submitting an issue please check that you’ve completed the following steps:
Describe the bug
In the 3.16 we introduced the new feature that allows to preload LCP images. When the image has AVIF/WEBP/Regular versions put together into the Picture markup, we're preloading different types of images causing browser to load more than without the feature applied.
Unfortunately, there's no way to preload images conditionally. Because of that we'll add to preload the very first
<source>
element from the<picture>
tag.Markups
The following markup:
https://pastebin.com/PSzP7Abq
Should become:
https://pastebin.com/jS2UHg83
The following markup:
https://pastebin.com/uvmYgm9E
Should become:
https://pastebin.com/6d4wTdv7
Expected behavior
We should only preload the first source element in the picture tag. If it's AVIF, then we should preload AVIF image(s), if it's WEBP, then we should preload the WEBP image(s).
Additional context
The markups live can be seen here and here.
Acceptance Criteria (for WP Media team use only)
types
are defined within the picture tagsource
img
) should be excluded from the lazyloadThe text was updated successfully, but these errors were encountered: