High LCP even after some optimization

Hi everyone,

I’m currently dealing with very high Largest Contentful Paint (LCP) times on my site, and I’m a bit at a loss as to what’s causing it.

At first, I suspected Google Ads might be the culprit due to the deferred loading behavior, but I’ve currently removed all ads entirely for testing — and still, the LCP is extremely high. For example, I’m seeing values like 14.4 seconds on this post:
:backhand_index_pointing_right: MSC Meraviglia: Verspätungen in Port Canaveral sorgen für Ärger bei Gästen 🚢

That page doesn’t load any third-party resources — just content from my own server.

My setup:

  • Server: AMD 9950 CPU, 16 GB RAM, NVMe SSD
  • Web server: nginx
  • CDN/Proxy: Cloudflare with Rocket Loader (enabling/disabling it doesn’t change the LCP much)
  • Images: Loaded via <picture> with modern, lightweight formats
  • Caching: Proper caching headers for images and static content
  • Traffic: Server isn’t under load when these measurements are taken

So far, I’ve tried removing ads, testing with/without Rocket Loader, and optimizing image delivery. Still, the LCP remains stubbornly high. I’m starting to wonder if I’m overlooking something obvious.

Has anyone run into similar issues or have ideas where I could look next?

Thanks in advance!

Turn the announcement bar off.

1 Like

Thank you! I’ve turned off the announcement-bar and still have 10.5s LCP.

Looking better!

I think you can take out the too-high CLS by adding the height to the feature image. (Or an aspect ratio + width.)

Ah, maybe some caching delay. Yes, not the LCP looks better.

Goodbye announcement bar :(

For the feature image i’m using this code from the ghost wiki:

 <picture>
        <!-- AVIF format -->
        <source
                srcset="{{img_url feature_image size="xs" format="avif"}} 160w,
                        {{img_url feature_image size="s" format="avif"}} 320w,
                        {{img_url feature_image size="sm" format="avif"}} 450w,
                        {{img_url feature_image size="m" format="avif"}} 600w,
                        {{img_url feature_image size="ml" format="avif"}} 700w,
                        {{img_url feature_image size="l" format="avif"}} 960w,
                        {{img_url feature_image size="xl" format="avif"}} 1200w,
                        {{img_url feature_image size="xxl" format="avif"}} 2000w"
                sizes="(max-width: 1200px) 100vw, 1120px"
                type="image/avif"
        >
        <!-- WebP format -->
        <source
                srcset="{{img_url feature_image size="xs" format="webp"}} 160w,
                        {{img_url feature_image size="s" format="webp"}} 320w,
                        {{img_url feature_image size="sm" format="webp"}} 450w,
                        {{img_url feature_image size="m" format="webp"}} 600w,
                        {{img_url feature_image size="ml" format="webp"}} 700w,
                        {{img_url feature_image size="l" format="webp"}} 960w,
                        {{img_url feature_image size="xl" format="webp"}} 1200w,
                        {{img_url feature_image size="xxl" format="webp"}} 2000w"
                sizes="(max-width: 1200px) 100vw, 1120px"
                type="image/webp"
        >
        <!-- Original format fallback -->
        <img
                srcset="{{img_url feature_image size="xs"}} 160w,
                        {{img_url feature_image size="s"}} 320w,
                        {{img_url feature_image size="sm"}} 450w,
                        {{img_url feature_image size="m"}} 600w,
                        {{img_url feature_image size="ml"}} 700w,
                        {{img_url feature_image size="l"}} 960w,
                        {{img_url feature_image size="xl"}} 1200w,
                        {{img_url feature_image size="xxl"}} 2000w"
                sizes="(max-width: 1200px) 100vw, 1120px"
                src="{{img_url feature_image size="xl"}}"
                alt="{{#if feature_image_alt}}{{feature_image_alt}}{{else}}{{title}}{{/if}}"
        >
    </picture>

I only added some additional sizes.

To prevent the CLS, the browser needs to know how big the image is going to be, so that it can reserve space for it while it loads. Is that image always the same proportions, or does it vary from page to page?

(I’m seeing the CLS on some but not all mobile loads. Looks like a bit of a race condition somewhere…)

Yes, it varies from page to page.

Edit: But even the LCP doesn’t seem to be consistently fixed. If I test the PageSpeed every 5 minutes, sometimes the LCP is good (as you mentioned), and other times it’s still around 13–15 seconds. It might be an issue with the CDN, or maybe I need to switch from Cloudflare to another CDN. I’m not sure.

Might be interesting to stick Cloudflare in development mode and see if the behavior becomes more consistent.

Caching makes it a lot harder to decide if you’ve fixed a problem, or just caught the cache right before it expires instead of right after.

I’ve enabled development mode, but the LCP is still high. I have no idea why it’s sometimes high and other times low. My gut feeling is that it might be server-side (although the hardware is overpowered for this blog) or due to the free Cloudflare plan with basic CDN/caching slowing things down.
Since I couldn’t shake the feeling, I briefly disabled the proxy mode entirely – the LCP dropped to 2 seconds. Apparently, Cloudflare is the issue here.

Interesting result! Is it now consistently low? (I’ve had way too many times I thought I’d fixed pagespeed only to discover I’d caught an oddball run instead.)

It still have some ping-pong effect but overall it seems to be lower.

1 Like

I’ve now switched to Bunny CDN. I’ll monitor the next 14 days and then see if it’s better than with Cloudflare. Current monitoring already shows significantly lower LCP than before. Now I just need to find another way to block the bad Python newsletter signups. Previously, I did it with custom WAF rules in Cloudflare, but I’m sure I’ll find another solution. Thanks so far!

LCP seems primarily related to feature image? Eg. 96 score on this Meine-Landausflüge.de 10% Rabatt über 2kreuzfahrer.de - which has no feature image

I’m not too sure about that code snippet - would be curious if you have different results with a simpler output like:

     {{#if feature_image}}
      <figure class="gh-feature-image">
          <img
              srcset="{{img_url feature_image size="s"}} 300w,
                      {{img_url feature_image size="m"}} 600w,
                      {{img_url feature_image size="l"}} 1000w,
                      {{img_url feature_image size="xl"}} 2000w"
              sizes="(max-width: 1000px) 1000px, 2000px"
              loading="lazy"
              src="{{img_url feature_image size="xl"}}"
              alt="{{#if feature_image_alt}}{{feature_image_alt}}{{else}}{{title}}{{/if}}"
          />
          {{#if feature_image_caption}}
              <figcaption>{{feature_image_caption}}</figcaption>
          {{/if}}
      </figure>
      {{/if}}