woocommerce / woocommerce

A customizable, open-source ecommerce platform built on WordPress. Build any commerce solution you can imagine.
https://woocommerce.com
9.42k stars 10.77k forks source link

Single Image in product gallery generate CLS with FlexSlider #30893

Open Mte90 opened 3 years ago

Mte90 commented 3 years ago

Prerequisites (mark completed items with an [x]):

Describe the bug Right now if you have a product with a gallery with FlexSlider you have a CLS of 0.13~ just because of that image on mobile. This is enough to alert Google Lighthouse, that has a max of 0,1 to avoid notices (as we are above there is an alert). Some examples documented on the web about the issue:

Honestly it is surprising that WooCommerce has this issues with all the users around the world and how much the Core Web Vitals are important for all the users and customers of Automattic.

Expected behavior Don't have CLS at all.

Steps to reproduce the bug (We need to be able to reproduce the bug in order to fix it.) Steps to reproduce the bug:

  1. Go to single product with Chrome
  2. Check the CLS

Isolating the problem (mark completed items with an [x]):

juliaamosova commented 3 years ago

Hi @Mte90,

Thank you for opening the issue! It requires further feedback from the WooCommerce Core team. I am adding the needs developer feedback label to this issue so that the Core team could take a look.

Please note it may take a few days for them to get to this issue. Thank you for your patience.

Mte90 commented 2 years ago

I don't think that https://github.com/woocommerce/woocommerce/pull/31407 in 6.1.0 fixed the issue but maybe helps and only a bit of test will help on that. The issue of opacity it is still present, I dont know what to do, what you think @erikyo @jeffstieler?

erikyo commented 2 years ago

As far i can understand @Mte90 is referring to the fact that the opacity of thumbnail images is set to 0 here and then set to true by js\frontend\ single-product.js during init.

If in the past could be happy for this sort of lazy-loading nowadays i think it would be better to leave it to a specialized plugin... for my small experience i must say that this lazy-loading often conflicted with optimization plugins (like lazysites) so i think it would be ideal to remove that code

erikyo commented 2 years ago

Any news? it would be advisable to remove any kind of lazy-loading from all Above-the-fold images because this can delay the larger paint content.

The @Mte90 fix will cut product page LCP of 0.25s, I guess many users would have it immediately if they knew of the advantage that brings!

someka commented 2 years ago

Hi guys. I am following this thread since a few months and I am curious if there is any script, code (css rule, php function whatever..) that we can apply to our own site and get this LCP-CLS issues improved a bit? I see a commit is linked but, as a non-developer website owner, I can't understand easily what to do with it. Sorry for the noob question.

erikyo commented 2 years ago

hi @someka could you give a try at this branch? https://github.com/woocommerce/woocommerce/compare/trunk...Mte90:flexslider-custom-nav-no-template

This should solve completely the issue with the CLS because the nav was generated with the page template and you don't need to wait for js and flexslider to be loaded before get nav the slideshow nav

In addition will fix some broken thing like vertical slider or fade, and allows to choose the number of thumbnail for row

add_filter( 'woocommerce_single_product_carousel_options', 'filter_single_product_carousel_options' );
function filter_single_product_carousel_options( $options ) {
    $options['direction'] = 'vertical';
    // OR
    // $options['animation'] = 'fade';
    return $options;
}

add_filter( 'woocommerce_product_thumbnails_columns', function () { return 5; } );

let me know!

ps. to answer you, this pr is moving forward but after a recent discussion with @jeffstieler on slack I made some changes that still need to be reviewed.

someka commented 2 years ago

Hi @erikyo Thanks for the guidance and the code. CLS: I have tried it and it apparently improved CLS. (even though it did not completely make it zero. Still shows the main image as a source for layout shift. But there are lots of things to consider, so not so easy to know) LCP: It didn't have big effect on LCP. Still red. FOUT: One more thing: now after removing the opacity cover, now there is the FOUT problem I think. Slider just flickers/flashes during load. (by the way, this is an example URL from our website I work on these issues, for your reference in case you may want to know. I have changed back the code after a few tries. fyi..)

erikyo commented 2 years ago

Hi @someka thanks for provide a feedback, really appreciated.

I think the flicker issue occurs to you because the thumb width is not set correctly when the items are more than 5, this is something that comes from the woocommerce stylesheet and I guess if the slider actually works in your website is because in your template there are some customizations (and this could even cause that flickering).

But this may do the trick fixing the missing style:

.single-product div.product .woocommerce-product-gallery.woocommerce-product-gallery--columns-6 .flex-control-thumbs li {width:16.667%}

About CLS/LCP the PR will improve only the time to get the above the fold ready. This because simply changes when the images are loaded, but since the images are exactly the same resize the time to load the whole page will not change at all (downloaded images and data are the same). What you noticed and what I expect, is the time to get the first view of the single product page ready and this is assured from the way the thumbs were loaded... the images are nested into page with php during the generation of the page and not like actually flexslider does, waiting for jquery to load before add the thumbnail to the page. This gives me a big improvement on some websites but depends on the number of thumbs and the image format used (if they are png jpg webp etc). Generally I could say this PR behaves better with less optimized images or if there are many (as in your case), because the range is greater so therefore also the margin of improvement