• Resolved ckihneman

    (@ckihneman)


    The default placeholder src that is set on lazyloaded images is a base64 encoded image. This image is square and forces the image into a square aspect ratio while the source image is loaded. This causes Cumulative Layout Shift (CLS) on every single image that is not square.

    CLS is a core “web vital” as set by Google. They have made it into a ranking signal. This means every single one of your users is negatively impacted by using lazy loading via your plugin. Countless sites.

    On the latest version of your plugin (3.8.4 at time of writing), in core/modules/class-lazy.php line 467 you have the line:

    
    Helpers\Parser::add_attribute( $new_image, 'src', 'data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==' );
    

    This forces the square base64 encoded image in as a placeholder. I recommend a couple things from here:

    First, your team needs to understand the google web vitals, specifically CLS.

    Then the best service you could give your users is to allow the natural width and height on the img tag to take over. Anything impacting those dimensions unnaturally will most likely negatively impact CLS, which could impact search engine ranking scores. So if you want to use a base64 image, you need a method of creating a placeholder that is at the very least the same aspect ratio of the source image, but should really be the same dimensions all together. It will need testing to ensure no CLS.

    However, in my case, I spent a good amount of time tracking this all down, to that one line of code. And for me, no base64 placeholder image makes my site work much more smoothly, and removes CLS for every single image that was lazy loaded, which can compound on pages with lots of image, resulting in a very poor CLS score.

    So, I could very easily comment out the line of code, and the problem is “fixed”. But as a potential stop-gap that is backwards-compatible and would help other users, update the line of code with a filter on the placeholder src like so:

    
    Helpers\Parser::add_attribute( $new_image, 'src', apply_filters( 'wp_smush_lazy_load_placeholder_src', 'data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==' ) );
    

    This means in my theme, I can add the following to not use your base64 image:

    
    add_filter('wp_smush_lazy_load_placeholder_src', function($src) {
        return '';
    });
    

    The only enhancement to this filter would be to pass any image info to the filter (mainly width and height) so the user could dynamically determine what placeholder to use, if desired.

    And just to note, I’m not the only user noticing this issue, as there are closed topics from a month and a year ago. This is an issue, you need to deal with it, and you need to promote good patterns for your users. I’d imagine most users will not notice and just carry on with CLS all over their site. Please, help those people out, and fix the CLS issues in your base plugin.

    https://www.ads-software.com/support/topic/lazy-loading-leads-to-cls/
    https://www.ads-software.com/support/topic/preventing-lazyload-reflow/

    • This topic was modified 3 years, 7 months ago by ckihneman.
    • This topic was modified 3 years, 7 months ago by ckihneman.
Viewing 10 replies - 1 through 10 (of 10 total)
  • Plugin Support Patrick – WPMU DEV Support

    (@wpmudevsupport12)

    Hi @ckihneman

    Thank you for reporting this.

    We sent this to our developers for further discussion, the Google metrics has been changed and avoid CLS is important.

    Best Regards
    Patrick Freitsa

    Plugin Support Patrick – WPMU DEV Support

    (@wpmudevsupport12)

    Hi @ckihneman

    I made some extra tests.

    Our developers confirmed to avoid the CLS your image need to have a fixed width/height attributes.

    If we use the height auto it will get the lazyload sizes and then yes, can cause the CLS.

    https://ibb.co/LPsknyR

    Also, the latest versions of WordPress should auto adjust all images, in case we remove the height auto and use the native tools you can see the container size is pre-set as 600px even the 1px image.

    https://ibb.co/zH73sHG

    I have been playing with object-fit rules which seems to avoid well the CLS too as the image will have defined width/height.

    https://developer.mozilla.org/en-US/docs/Web/CSS/object-fit

    Let us know if you have any further question on this.
    Best Regards
    Patrick Freitas

    Thread Starter ckihneman

    (@ckihneman)

    In modern, responsive web development – most developers have something like this in their CSS.

    embed,
    iframe,
    img,
    object,
    video {
      max-width: 100%;
      height: auto;
    }

    If you don’t, you won’t have a responsive website. Some will even have width: 100% as well (if they know all their images are larger than their containers). You can’t just rely srcset to change the image source, the image still wont fit to it’s container (it will snap in size as the smaller image is loaded), which won’t pass design and marketing teams.

    Yes, the jank is caused by this – the natural width of the image gets picked up, height: auto kicks in, and boom, you have a square aspect ratio in your page until the real source loads in. But it’s still back to the base64 image as a placeholder src that is causing this in the first place. It’s the full interaction that causes CLS.

    Look, to take it a step further and convince you that something actually needs to be done about this on your end – I created a fresh WordPress site, using latest WordPress as of right now (Version 5.7.1). I edited the default sample page that comes with every base WordPress install. I added a large, wide image as the feature image. I added one large, wide image into the content below the first paragraph of text. Save, and test page.

    0 CLS on base WordPress install, no plugins, their base theme.

    This base theme built by WordPress ships with this CSS by default:

    img {
        height: auto;
        max-width: 100%;
        vertical-align: middle;
    }

    Now, I went to plugins in my new WordPress install, found your plugin, installed it, went through the configuration, enabling lazy loading in the process. I let the images be processed by your plugin. I go right back over, refresh the page, see the images are lazy loading, test with lighthouse…

    0.244 CLS with only your plugin and lazyloading active.

    This is the smoking gun, a base install of WordPress, only Smush and two images and now our CLS is over the 0.1 accepted tolerance. CLS only gets worse as you have wider images than not, or just more images. If you only had square images, you would get 0 CLS.

    I think you need to test solutions with different placeholder image, no placeholder image, or maybe something CSS related, potentially using object-fit as you mentioned. You gotta get to a place where a fresh install like I did with your plugin does not cause CLS. If you can’t get here, then you need to offer a solution to your users in your plugin description, noting the CLS issues and what they can do to get around it. Maybe consider adding my filter on the placeholder img src as well – I know I’ll get tired of having to find the line of code each time I want to update the plugin.

    Thanks for your time, I appreciate your response.

    Plugin Support Patrick – WPMU DEV Support

    (@wpmudevsupport12)

    Hi @ckihneman

    In modern, responsive web development – most developers have something like this in their CSS.

    Yes, that is correct but this approach is going to be updated in the future using the defined height and the responsive images.

    Look, to take it a step further and convince you that something actually needs to be done about this on your end – I created a fresh WordPress site, using latest WordPress as of right now (Version 5.7.1). I edited the default sample page that comes with every base WordPress install. I added a large, wide image as the feature image. I added one large, wide image into the content below the first paragraph of text. Save, and test page.

    Did you use the Gutenberg editor and the image block?

    It does use 100% but should have the correct container size since 5.7 regarding our developer.

    Best Regards
    Patrick Freitas

    Thread Starter ckihneman

    (@ckihneman)

    this approach is going to be updated in the future using the defined height and the responsive images.

    Please provide more context, or a link to this resource on potential upcoming web features that promise to fix a systemic issue in your plugin.

    Did you use the Gutenberg editor and the image block?

    Yes, I did.

    It does use 100% but should have the correct container size since 5.7 regarding our developer.

    What do you mean “correct container size”?

    As for modern best practices around this stuff, see optimizing for CLS. It all boils down to set a width and height on your images, and the browser ships with an aspect-ratio on all images as base browser CSS, which works to reserve the proper amount of space on responsive images.

    If there is some new trend on the way, please let me know. But browser vendors when out of their way to make this stuff “just work”. Which brings us back around to the placeholder base64 image src breaking this base browser functionality.

    Plugin Support Patrick – WPMU DEV Support

    (@wpmudevsupport12)

    Hi @ckihneman

    Please provide more context, or a link to this resource on potential upcoming web features that promise to fix a systemic issue in your plugin.

    Sorry, by this I mean exactly what the code that the shared code pointed for responsive images https://web.dev/optimize-cls/#modern-best-practice

    Also, it is safe to exclude the Lazy Load images for images that are visible in the page load using the exclusion feature:

    https://wpmudev.com/docs/wpmu-dev-plugins/smush/#lazy-loading

    Or the filter smush_skip_image_from_lazy_load

    Usage:

    <?php
    
    add_filter( 'smush_skip_image_from_lazy_load', function( $status, $src, $image ) {
    
    	$site = get_site_url();
    
    	$exclude = [
    		'/wp-content/uploads/2021/04/img-1.jpg',
    		'/wp-content/uploads/2021/04/img-2.jpg',
    	];
    
    	foreach($exclude as $img){
    		if ( $site . $img === $src ) {
    			$status = true;
    		}
    	}
    
    	return $status;
    
    }, 99, 3 );

    What do you mean “correct container size”?

    Similar to what we use for Ads to reserve that container slot size and avoid big jumps in the layout:

    https://developers.google.com/publisher-tag/guides/minimize-layout-shift

    If there is some new trend on the way, please let me know. But browser vendors when out of their way to make this stuff “just work”. Which brings us back around to the placeholder base64 image src breaking this base browser functionality.

    I think we are on the same page here.

    Google will report in the lighthouse test if we don’t use the width and height, using the 100% which is the responsive way it is a good idea to set your image container a min-height to avoid the big layout jumps.

    It is safe to exclude the visible images on page load from lazyload and it will not hurt the PSI score and should fix the CLS issues.

    The Scripts won’t get your size image to set the base64 or any other size to the Lazy Load which can cause some CLS depending on those images are loaded.

    As you can see the example in my previous reply using auto vs a defined size.

    We also sent this to the plugin team for further discussion to verify how we can improve any lazyload aspect in the Smush.

    Best Regards
    Patrick Freitas

    Thread Starter ckihneman

    (@ckihneman)

    Skipping images negates the point of using the plugin in the first place. This is a non-solution.

    The webvitals doc states:

    To ensure width and height attributes can be set, each image should use the same aspect ratio.

    Your default placeholder src image is breaking this. It’s not the same dimension as the image that will load unless it’s a square image.

    The point I’m continuing to try to make is that out of the box, lazyloading with your plugin causes CLS, and CLS is now a ranking factor for google. There isn’t much more to be said.

    While I appreciate your time here and thank you for the plugin, you are skirting around the core issue, as it was not addressed in the other threads trying to bring this up. There just has to be a better way than with the default base64 image. My CLS scores improve ACROSS MY WHOLE SITE (millions of visits/month) by commenting out that line of code mentioned in my first response. You have to realize something is very, very wrong if this is the case.

    If I have to continue to make an edit to the plugin source code – I’ll be looking for other lazyloading solutions, or roll my own.

    I’d also be happy to discuss options with your team further to find a real solution.

    It took me a while to come to the conclusion that WPMU Smush was causing me some major formatting issues and performance issues for Woocommerce Archive pages where I have Featured Imaged Thumbnail set to a non square image. My site has all portrait aspect ratio images, Magazine Covers. The discussion here is over my head, all I can say is that when I disabled Lazy Loading in Smush on my Archive Pages, all my problems went away.

    • This reply was modified 3 years, 6 months ago by iknowtech.
    Plugin Support Patrick – WPMU DEV Support

    (@wpmudevsupport12)

    Hi @iknowtech & @ckihneman

    Sorry for the delay here.

    I reported this situation to the plugin team for further discussion, I hope we can improve this in a future release.

    Best Regards
    Patrick Freitas

    Plugin Support Patrick – WPMU DEV Support

    (@wpmudevsupport12)

    Hi There

    I hope you are doing well and safe!

    We haven’t heard from you in a while, I’ll mark this thread as resolved.

    Feel free to let us know if you have any additional question or problem.

    Best Regards
    Patrick Freitas

Viewing 10 replies - 1 through 10 (of 10 total)
  • The topic ‘Lazy Loading, issues with CLS and your default placeholder image’ is closed to new replies.