Fixing LCP is often simpler than it looks. Learn how to identify the real bottlenecks, optimize hero images, and stop wasting time on minor tweaks.

We’ve all been there: staring at a Lighthouse report that screams in red, telling us our Largest Contentful Paint (LCP) is hovering somewhere around 4 seconds. It’s frustrating when you know the site feels fast, but the metrics say otherwise. Last month, I spent about two days chasing a phantom LCP regression on a client site, only to realize the issue wasn't the framework—it was how we handled our hero section.
Fixing LCP isn't about micro-optimizing every script on the page. It's about identifying the one element that defines the user's perception of "loaded" and clearing the runway for it.
When you’re fixing LCP issues, you don’t need to rewrite your entire codebase. Most of the time, the culprit is one of three things: an unoptimized hero image, a render-blocking stylesheet, or a server-side delay in generating the initial HTML.
Before you touch a line of code, use the Chrome DevTools "Performance" tab. Look for the "Largest Contentful Paint" marker in the timings track. If that marker is happening way after the initial request, you’ve got a clear target.
The most common offender is the hero image. If your LCP element is an <img> tag, it’s likely waiting for the CSS to load, or worse, it’s being lazy-loaded by default.
Stop lazy-loading your LCP image. It sounds counterintuitive, but loading="lazy" is the enemy of a fast hero section. If the browser doesn't know the image is important until it starts parsing the layout, you're losing hundreds of milliseconds.
HTML<!-- Do this --> style="color:#808080"><style="color:#4EC9B0">img src="hero.webp" fetchpriority="high" alt="Hero banner"> <!-- Not this --> style="color:#808080"><style="color:#4EC9B0">img src="hero.webp" loading="lazy" alt="Hero banner">
By adding fetchpriority="high", you’re telling the browser: "This is the most important thing on the page, grab it first."
Sometimes your LCP is delayed because the browser is waiting for a massive 200KB CSS file to download and parse before it even attempts to render the hero section. Even if you aren't using a complex setup like building a custom WordPress plugin with a clean architecture, you can still fall into the trap of monolithic stylesheets.
If your hero styles are buried in a giant style.css, extract the critical CSS—the styles needed for the header and hero—and inline them in the <head>. It’s a bit of a manual chore, but it can shave roughly 300ms to 500ms off your LCP in one go.
If your Time to First Byte (TTFB) is slow, your LCP will be slow by default. You can’t paint what you haven't received. If you’re running a database-heavy stack, ensure you’re caching the HTML response. While WordPress database optimization: implementing HyperDB for scaling is a great long-term strategy for high-traffic sites, simple object caching often solves the immediate TTFB problem for most applications.
I once tried to fix an LCP issue by aggressively minifying every single JavaScript bundle on the site. I thought fewer bytes would equal a faster paint. All I managed to do was increase the CPU time spent parsing JS, which actually blocked the main thread longer and delayed the paint even more.
I learned the hard way: if the LCP element is an image or text, stop obsessing over JS bundles. Focus on the network path for that specific element.

Don't trust lab data alone. Use the "Web Vitals" extension to see what's actually happening in your current session. When I’m testing, I look for a consistent improvement across three different network throttles: Fast 3G, Slow 4G, and No Throttling. If you see a consistent drop of even 100ms, you’re moving in the right direction.
Q: Does moving my LCP image to a CDN actually help? A: Yes, but only if the CDN is configured to keep the connection warm. If the image is still behind a slow DNS lookup or a cold connection, the CDN won't save you.
Q: Is it better to use a background image in CSS or an <img> tag?
A: Use an <img> tag for LCP elements. Browsers can discover <img> tags much earlier in the document stream than they can discover a background image hidden inside a CSS file.
Q: What if my LCP is a text block?
A: If it's a large <h1>, make sure you aren't using a custom web font that causes a "Flash of Invisible Text" (FOIT). Use font-display: swap or, even better, preload the font file if it’s critical.

Fixing LCP is about prioritization. You’re essentially acting as a traffic controller, telling the browser which files are the VIPs and which ones can wait. I’m still experimenting with new ways to prioritize early-loading assets, and honestly, it’s a constant game of cat and mouse as browsers update their rendering engines. Start with the fetchpriority attribute and the critical CSS—that alone solves the majority of cases I’ve encountered.
Image optimization that moves the needle is about more than just compression. Learn how to use modern formats and responsive delivery to slash LCP times.