WordPress / performance

Performance plugin from the WordPress Performance Group, which is a collection of standalone performance modules.
https://wordpress.org/plugins/performance-lab/
GNU General Public License v2.0
350 stars 94 forks source link

Picture element: Small image size issues #1439

Closed mukeshpanchal27 closed 3 weeks ago

mukeshpanchal27 commented 1 month ago

Bug Description

Issue reported at https://github.com/WordPress/performance/issues/1417#issuecomment-2265517786

Image itself is 600 × 400 in jpg, in admin there are thumbnail (150x150px and full size ). No medium, no medium_large etc, because medium is 768x512px with center crop.

Steps to reproduce the different cases

Case 1: It will not return Picture element as WP didn't generate any sub-sizes for the image so it will return early here: https://github.com/WordPress/performance/blob/trunk/plugins/webp-uploads/picture-element.php#L27-L29

Case 2 & 3: It should return the source for picture element.

mukeshpanchal27 commented 1 month ago

1430 remove wrapper picture tag when the source is empty.

@westonruter feedback on PR:

Why isn't there a fallback JPEG for this generated AVIF image? The size of the image being uploaded shouldn't matter. If uploading a 10x10 JPEG image, this should still result in an AVIF/WebP image being generated in addition to the JPEG fallback (if that option is enabled). The PICTURE should still be used even if the IMG lacks a srcset because it should provide the JPEG fallback for the AVIF.

westonruter commented 1 month ago

In each of the cases, an AVIF is the format being served in the IMG tag, not the expected fallback JPEG.

Issue that has been filed as #1447 I think I found another problem which may be the underlying cause of some of the issues we've seen: 1. Activate the plugin 2. Leave the "Also output JPEG" option disabled 3. Upload a few JPEG images 4. Insert these images as a large size in Image blocks 5. Enable "Also output JPEG" and the "Picture element" options Bug: Go to the frontend and see that it is generating the wrong markup with the `IMG` being the modern format, not the JPEG fallback: ```html ``` The problem here is that there was no JPEG fallback available for this image, so it should be ineligible for the picture element. It should instead be generating: ```html ``` In contrast, if I upload another image after I have the "Also output JPEG" and the "Picture element" settings enabled, then I see what is expected: ```html ``` There should be some message shown with the Picture element setting to say something like: > Picture elements will only be used when JPEG fallback images are available. So any images you have uploaded while the "Also generate JPEG" setting was disabled won't get served in any picture elements.
westonruter commented 1 month ago

Maybe this should be split into another issue?

UPDATE: See https://github.com/WordPress/performance/issues/1447

mukeshpanchal27 commented 1 month ago

@westonruter Please check my answers.

In each of the cases, an AVIF is the format being served in the IMG tag, not the expected fallback JPEG.

The fallback JPEG will be added in PR #1408 once it merge it will return correct fallback image.

Bug: Go to the frontend and see that it is generating the wrong markup with the IMG being the modern format, not the JPEG fallback:

<picture class="not-transparent wp-picture-99" style="--dominant-color: #828ca3; display: contents;">
    <source type="image/webp" srcset="http://localhost:8888/wp-content/uploads/2024/08/Spectacled_weaver_Ploceus_ocularis_ocularis_male_Mbombela-828x1024.webp 828w, http://localhost:8888/wp-content/uploads/2024/08/Spectacled_weaver_Ploceus_ocularis_ocularis_male_Mbombela-242x300.webp 242w, http://localhost:8888/wp-content/uploads/2024/08/Spectacled_weaver_Ploceus_ocularis_ocularis_male_Mbombela-768x950.webp 768w" sizes="(max-width: 650px) 100vw, 650px">
    <img data-has-transparency="false" decoding="async" width="828" height="1024" src="http://localhost:8888/wp-content/uploads/2024/08/Spectacled_weaver_Ploceus_ocularis_ocularis_male_Mbombela-828x1024.webp" alt="" class="not-transparent wp-image-99" srcset="http://localhost:8888/wp-content/uploads/2024/08/Spectacled_weaver_Ploceus_ocularis_ocularis_male_Mbombela-828x1024.webp 828w, http://localhost:8888/wp-content/uploads/2024/08/Spectacled_weaver_Ploceus_ocularis_ocularis_male_Mbombela-242x300.webp 242w, http://localhost:8888/wp-content/uploads/2024/08/Spectacled_weaver_Ploceus_ocularis_ocularis_male_Mbombela-768x950.webp 768w, http://localhost:8888/wp-content/uploads/2024/08/Spectacled_weaver_Ploceus_ocularis_ocularis_male_Mbombela-1241x1536.webp 1241w, http://localhost:8888/wp-content/uploads/2024/08/Spectacled_weaver_Ploceus_ocularis_ocularis_male_Mbombela-1655x2048.webp 1655w" sizes="(max-width: 650px) 100vw, 650px">
</picture>

The problem here is that there was no JPEG fallback available for this image, so it should be ineligible for the picture element. It should instead be generating:

<img data-has-transparency="false" decoding="async" width="828" height="1024" src="http://localhost:8888/wp-content/uploads/2024/08/Spectacled_weaver_Ploceus_ocularis_ocularis_male_Mbombela-828x1024.webp" alt="" class="not-transparent wp-image-99" srcset="http://localhost:8888/wp-content/uploads/2024/08/Spectacled_weaver_Ploceus_ocularis_ocularis_male_Mbombela-828x1024.webp 828w, http://localhost:8888/wp-content/uploads/2024/08/Spectacled_weaver_Ploceus_ocularis_ocularis_male_Mbombela-242x300.webp 242w, http://localhost:8888/wp-content/uploads/2024/08/Spectacled_weaver_Ploceus_ocularis_ocularis_male_Mbombela-768x950.webp 768w, http://localhost:8888/wp-content/uploads/2024/08/Spectacled_weaver_Ploceus_ocularis_ocularis_male_Mbombela-1241x1536.webp 1241w, http://localhost:8888/wp-content/uploads/2024/08/Spectacled_weaver_Ploceus_ocularis_ocularis_male_Mbombela-1655x2048.webp 1655w" sizes="(max-width: 650px) 100vw, 650px">

In which branch are you checking this? In #1375(Merged in trunk) we added check if "Also output JPEG" is disabled then it will return IMG instead of Picture element.

In contrast, if I upload another image after I have the "Also output JPEG" and the "Picture element" settings enabled, then I see what is expected:

<picture class="not-transparent wp-picture-102" style="--dominant-color: #62759f; display: contents;">
    <source type="image/webp" srcset="http://localhost:8888/wp-content/uploads/2024/08/Samango_monkey_Cercopithecus_mitis_erythrarchus_Mount_Sheba-1024x588-jpg.webp 1024w, http://localhost:8888/wp-content/uploads/2024/08/Samango_monkey_Cercopithecus_mitis_erythrarchus_Mount_Sheba-300x172-jpg.webp 300w, http://localhost:8888/wp-content/uploads/2024/08/Samango_monkey_Cercopithecus_mitis_erythrarchus_Mount_Sheba-768x441-jpg.webp 768w" sizes="(max-width: 650px) 100vw, 650px">
    <source type="image/jpeg" srcset="http://localhost:8888/wp-content/uploads/2024/08/Samango_monkey_Cercopithecus_mitis_erythrarchus_Mount_Sheba-1024x588.jpg 1024w, http://localhost:8888/wp-content/uploads/2024/08/Samango_monkey_Cercopithecus_mitis_erythrarchus_Mount_Sheba-300x172.jpg 300w, http://localhost:8888/wp-content/uploads/2024/08/Samango_monkey_Cercopithecus_mitis_erythrarchus_Mount_Sheba-768x441.jpg 768w" sizes="(max-width: 650px) 100vw, 650px">
    <img data-dominant-color="62759f" data-has-transparency="false" decoding="async" width="1024" height="588" src="http://localhost:8888/wp-content/uploads/2024/08/Samango_monkey_Cercopithecus_mitis_erythrarchus_Mount_Sheba-1024x588-jpg.webp" alt="" class="not-transparent wp-image-102" srcset="http://localhost:8888/wp-content/uploads/2024/08/Samango_monkey_Cercopithecus_mitis_erythrarchus_Mount_Sheba-1024x588-jpg.webp 1024w, http://localhost:8888/wp-content/uploads/2024/08/Samango_monkey_Cercopithecus_mitis_erythrarchus_Mount_Sheba-300x172-jpg.webp 300w, http://localhost:8888/wp-content/uploads/2024/08/Samango_monkey_Cercopithecus_mitis_erythrarchus_Mount_Sheba-768x441-jpg.webp 768w, http://localhost:8888/wp-content/uploads/2024/08/Samango_monkey_Cercopithecus_mitis_erythrarchus_Mount_Sheba-1536x882.jpg 1536w, http://localhost:8888/wp-content/uploads/2024/08/Samango_monkey_Cercopithecus_mitis_erythrarchus_Mount_Sheba-2048x1176.jpg 2048w" sizes="(max-width: 650px) 100vw, 650px">
</picture>

There should be some message shown with the Picture element setting to say something like:

Picture elements will only be used when JPEG fallback images are available. So any images you have uploaded while the "Also generate JPEG" setting was disabled won't get served in any picture elements.

This is expected output. Picture element return when both options are enabled. The PR #1408 removed the JPEG source from picture element and return fallback JPEG Image.

westonruter commented 1 month ago

In which branch are you checking this? In #1375(Merged in trunk) we added check if "Also output JPEG" is disabled then it will return IMG instead of Picture element.

I'm testing in trunk. The problem is that I uploaded an image when the "Also generate JPEG" option is off. So then later when I turn that option on and enable Picture element, there is no JPEG version to serve. And I instead incorrectly get a PICTURE element that has a WebP IMG tag, when PICTURE should only be served if the IMG is a JPEG.

This is expected output. Picture element return when both options are enabled. The PR #1408 removed the JPEG source from picture element and return fallback JPEG Image.

This is not the expected output. A PICTURE > IMG should never be WebP. It should only ever be JPEG. Again, I'm seeing this:

<picture
class="not-transparent wp-picture-126"
style="--dominant-color: #9a7372; display: contents"
><source
  type="image/webp"
  srcset="
    http://localhost:8888/wp-content/uploads/2024/08/IMG_20221031_130510-1024x768.webp 1024w,
    http://localhost:8888/wp-content/uploads/2024/08/IMG_20221031_130510-300x225.webp   300w,
    http://localhost:8888/wp-content/uploads/2024/08/IMG_20221031_130510-768x576.webp   768w
  "
  sizes="(max-width: 650px) 100vw, 650px" />
<img
  data-dominant-color="9a7372"
  data-has-transparency="false"
  fetchpriority="high"
  decoding="async"
  width="1024"
  height="768"
  src="http://localhost:8888/wp-content/uploads/2024/08/IMG_20221031_130510-1024x768.webp"
  alt=""
  class="not-transparent wp-image-126"
  srcset="
    http://localhost:8888/wp-content/uploads/2024/08/IMG_20221031_130510-1024x768.webp  1024w,
    http://localhost:8888/wp-content/uploads/2024/08/IMG_20221031_130510-300x225.webp    300w,
    http://localhost:8888/wp-content/uploads/2024/08/IMG_20221031_130510-768x576.webp    768w,
    http://localhost:8888/wp-content/uploads/2024/08/IMG_20221031_130510-1536x1152.webp 1536w,
    http://localhost:8888/wp-content/uploads/2024/08/IMG_20221031_130510-2048x1536.webp 2048w
  "
  sizes="(max-width: 650px) 100vw, 650px"
/></picture>

Both the PICTURE > SOURCE and the PICTURE > IMG are pointing to the WebP. This is incorrect.

I've filed this under https://github.com/WordPress/performance/issues/1447.

mukeshpanchal27 commented 3 weeks ago

After the implementation for fallback image #1408 and other improvement for Picture element these issue seems resolved.

Here is the result of each case that mention in description and it looks good to me. Closing the issue.

Case 1: Upload 100x100 size image.

<picture class="wp-picture-31" style="display: contents;">
  <source 
    type="image/webp" 
    srcset="http://localhost:8888/wp-content/uploads/2024/08/100X100-jpg.webp"
  >
  <img 
    decoding="async" 
    width="100" 
    height="100" 
    src="http://localhost:8888/wp-content/uploads/2024/08/100X100.jpg" 
    alt="" 
    class="wp-image-31" 
    style="object-fit:cover"
  >
</picture>

Case 2: Upload 200x200 size image. Select Full size image.

<picture class="wp-picture-34" style="display: contents;">
  <source 
    type="image/webp" 
    srcset="
      http://localhost:8888/wp-content/uploads/2024/08/200x200-jpg.webp 200w, 
      http://localhost:8888/wp-content/uploads/2024/08/200x200-150x150-jpg.webp 150w
    " 
    sizes="(max-width: 200px) 100vw, 200px"
  >
  <img 
    decoding="async" 
    width="200" 
    height="200" 
    src="http://localhost:8888/wp-content/uploads/2024/08/200x200.jpg" 
    alt="" 
    class="wp-image-34" 
    srcset="
      http://localhost:8888/wp-content/uploads/2024/08/200x200.jpg 200w, 
      http://localhost:8888/wp-content/uploads/2024/08/200x200-150x150.jpg 150w
    " 
    sizes="(max-width: 200px) 100vw, 200px"
  >
</picture>

Case 3: Upload 200x200 size image. Select Thumbnail size image.

<picture class="wp-picture-34" style="display: contents;">
  <source 
    type="image/webp" 
    srcset="
      http://localhost:8888/wp-content/uploads/2024/08/200x200-150x150-jpg.webp 150w, 
      http://localhost:8888/wp-content/uploads/2024/08/200x200-jpg.webp 200w
    " 
    sizes="(max-width: 150px) 100vw, 150px"
  >
  <img 
    decoding="async" 
    width="150" 
    height="150" 
    src="http://localhost:8888/wp-content/uploads/2024/08/200x200-150x150.jpg" 
    alt="" 
    class="wp-image-34" 
    srcset="
      http://localhost:8888/wp-content/uploads/2024/08/200x200-150x150.jpg 150w, 
      http://localhost:8888/wp-content/uploads/2024/08/200x200.jpg 200w
    " 
    sizes="(max-width: 150px) 100vw, 150px"
  >
</picture>