Skip to content
Back to Blog
Performance8 min read

Core Web Vitals Optimization: [Solved] 6 Fixes for LCP

Six practical server-side and front-end changes that push your Largest Contentful Paint score above Google's threshold and keep users on your site.

Written by Abdul AbrorTechnical Hosting Support Engineer
Core Web Vitals Optimization: [Solved] 6 Fixes for LCP
On this page

Largest Contentful Paint measures how long your biggest above-the-fold element takes to render. Google wants that under 2.5 seconds on a good connection. Most shared hosting sites I've worked with land somewhere between three and five seconds out of the box, which puts them in the "needs improvement" or "poor" bucket.

LCP isn't just a score. When your hero image or headline takes four seconds to appear, visitors leave. In support tickets I've handled, slow LCP always traces back to one of six fixable issues: bloated images, render-blocking resources, slow server response, missing resource hints, unoptimized fonts, or client rendering delays. Let's walk through each fix.

1. Compress and serve next-gen image formats

Your LCP element is often a hero image or banner. If that file weighs two megabytes and arrives as a JPEG, you've already lost.

Convert images to WebP or AVIF. WebP cuts file size by 25-35 percent compared to JPEG at the same visual quality; AVIF does even better but has spottier browser support. Most CDN providers and WordPress caching plugins can auto-convert on the fly.

On the server side, check your image compression level. A quality setting of 80-85 for JPEG and WebP is invisible to the human eye but saves bandwidth. I've seen hosting accounts serve images at quality 100, which doubles file size for no perceptible gain.

If you're on cPanel shared hosting, install an image optimization plugin or enable WebP in your caching plugin settings. For VPS or dedicated servers, configure your web server to serve WebP when the browser accepts it:

<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteCond %{HTTP_ACCEPT} image/webp
  RewriteCond %{DOCUMENT_ROOT}/$1.webp -f
  RewriteRule ^(.*)\.(?:jpe?g|png)$ $1.webp [T=image/webp,E=accept:1,L]
</IfModule>

That snippet tells Apache to serve the WebP variant if it exists and the browser supports it.

2. Eliminate render-blocking JavaScript and CSS

Browsers parse HTML top to bottom. When they hit a <script> or <link rel="stylesheet"> tag in the head, they stop rendering and fetch that resource. If your CSS bundle is 200 KB and hosted on a slow CDN, your LCP element won't paint until that file downloads and parses.

Inline critical CSS directly in the <head>. Critical CSS is the minimal subset of styles needed to render above-the-fold content. Extract it with a tool or plugin, then put it in a <style> block. Load the full stylesheet asynchronously:

<link rel="preload" href="/styles/main.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
<noscript><link rel="stylesheet" href="/styles/main.css"></noscript>

For JavaScript, add defer or async attributes. defer keeps scripts from blocking the parser and executes them in order after the DOM is ready. async downloads in parallel but executes as soon as available, which can break dependencies. Use defer for most scripts.

WordPress users: disable jQuery and other libraries in the head if they're not needed above the fold. Many themes load jQuery, Font Awesome, and analytics libraries synchronously in the header. Move them to the footer or defer them.

3. Reduce server response time (TTFB)

Time to First Byte is the delay between the browser request and the first byte of HTML arriving. Google wants TTFB under 800 milliseconds. Slow TTFB delays everything, including LCP.

On shared hosting, TTFB spikes come from PHP execution time, database queries, or server overload. Check your hosting metrics first. If CPU or memory usage is pegged, upgrade your plan or migrate to a VPS.

Enable opcode caching. PHP opcode cache (OPcache) stores compiled PHP bytecode in memory so the server doesn't recompile scripts on every request. On cPanel, this is usually enabled by default under PHP settings. On a self-managed server:

sudo apt install php-opcache
sudo systemctl restart php-fpm

Verify it's active:

php -i | grep opcache

You should see opcache.enable => On.

For WordPress sites, install an object cache (Redis or Memcached) to store database query results. A typical WordPress page runs dozens of queries; caching them drops TTFB from 1.2 seconds to 300 milliseconds.

If you're behind Cloudflare, enable Argo Smart Routing or use their CDN to cache HTML. Standard Cloudflare caching skips HTML by default, so TTFB still depends on your origin server unless you write a page rule or enable APO (Automatic Platform Optimization for WordPress).

4. Preload and prefetch critical resources

Resource hints tell the browser what to fetch before it needs it. preload forces an early fetch for resources you know the page will use; prefetch hints at resources for the next navigation.

For LCP, preload your hero image:

<link rel="preload" as="image" href="/images/hero.webp" type="image/webp">

Put that in the <head>, above any stylesheets. The browser will start downloading the image immediately, in parallel with CSS and JavaScript, instead of waiting until the HTML parser reaches the <img> tag.

If your LCP element is a background image defined in CSS, preload it the same way. Just make sure the href matches the URL in your stylesheet exactly, including any CDN prefix.

Preconnect to third-party domains that serve critical resources:

<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://cdn.example.com" crossorigin>

Preconnect completes the DNS lookup, TCP handshake, and TLS negotiation early. That saves 200-500 milliseconds on the first request to that domain.

5. Optimize web font loading

Custom fonts delay LCP if the browser blocks text rendering while the font downloads. By default, most browsers use FOIT (flash of invisible text): they hide text for up to three seconds waiting for the web font.

Use font-display: swap in your @font-face rules:

@font-face {
  font-family: 'YourFont';
  src: url('/fonts/yourfont.woff2') format('woff2');
  font-display: swap;
}

swap tells the browser to render text immediately in a fallback font, then swap in the web font when it arrives. Users see content faster.

Host fonts locally instead of linking to Google Fonts or Adobe Fonts. Third-party font services add extra DNS lookups and HTTPS handshakes. Download the WOFF2 files and serve them from your own domain or CDN.

If your LCP element contains text styled with a web font, preload that font file:

<link rel="preload" as="font" type="font/woff2" href="/fonts/yourfont.woff2" crossorigin>

The crossorigin attribute is required even for same-origin fonts because font requests are always CORS.

6. Minimize client-side rendering delays

If your page relies on JavaScript frameworks (React, Vue, Angular) to render the LCP element, you're waiting for the framework bundle to download, parse, execute, and then paint. That's slow.

Server-side rendering or static site generation solves this. Pre-render your HTML on the server so the browser receives a complete page with the LCP element already in the markup. Modern frameworks all support SSR or SSG modes.

For WordPress, avoid page builders that render everything via JavaScript. Elementor and Divi can push LCP past four seconds because they inject styles and content dynamically. Classic WordPress themes with server-rendered HTML are faster.

If you must use a JavaScript-heavy stack, code-split your bundles and defer non-critical scripts. Load only the JavaScript needed for above-the-fold content synchronously; lazy-load the rest.

Check your third-party scripts too. Analytics tags, chat widgets, and ad networks inject render-blocking code. I've seen a single poorly configured analytics script add 1.5 seconds to LCP. Load these asynchronously or defer them entirely.

What actually moves the needle?

In the tickets I've handled, three changes usually account for 80 percent of the LCP improvement: switching to next-gen image formats, reducing TTFB through better caching, and eliminating render-blocking CSS. Start there.

Preloading your LCP image is the fastest single fix—it takes two minutes and often cuts LCP by half a second. After that, tackle server response time if TTFB is above one second, then work through the other optimizations.

Run PageSpeed Insights or WebPageTest after each change to confirm the impact. LCP scores fluctuate based on network conditions, so test multiple times. A score that bounces between 2.3 and 2.7 seconds is still in the "good" range; don't chase perfection.

Does CDN help LCP?

Yes, if your origin server is slow or geographically distant from your users. A CDN caches static assets (images, CSS, JavaScript) at edge locations closer to visitors. That reduces latency and speeds up resource delivery. For LCP, the biggest win comes from serving your hero image through the CDN and enabling HTML caching if supported.

Should I lazy-load the LCP image?

No. Never lazy-load your LCP element. Lazy-loading defers image loading until the element is near the viewport, which delays LCP. Reserve lazy-loading for below-the-fold images.

Can server location affect LCP?

Absolutely. If your server is in Europe and your visitors are in Asia, TTFB and resource fetch times spike. A CDN mitigates this for cached assets, but dynamic HTML still comes from the origin. Consider a VPS closer to your audience or use a multi-region CDN with edge caching.

Why is my LCP element changing?

PageSpeed Insights identifies the largest visible element above the fold. If your layout shifts during load (ads appear, images resize), the LCP element can change mid-render. Fix layout shifts by reserving space for images and ads with explicit width and height attributes.

Start with TTFB and images

Most LCP problems come down to slow servers and heavy images. Check your TTFB first—if it's over a second, no amount of front-end optimization will save you. Enable opcode caching, upgrade your hosting plan, or add an object cache.

Once TTFB is under control, compress your hero image and serve it in WebP or AVIF. Preload it in the head. Those two changes alone will often push your LCP score into the green. The other fixes—removing render-blocking resources, optimizing fonts, and reducing client-side rendering—compound the improvement and keep your score stable under load.