Largest Contentful Paint (LCP) is the unsung hero of Core Web Vitals. It’s the most straightforward of the three to optimize, and the only one that’s consistent between lab data and field results.
Yet, it’s also the most neglected. According to CrUX data, fewer than half of origins deliver a Good LCP.
Let’s fix that.
Disclaimer before we dive in: your site could be — in actuality — fast as hell. But Google Page Speed expects to see specific metrics on key indicators. LCP is a significant page speed score grading factor.
<img>
objects for above the fold hero areas. All other elements are slower and far inferior for LCP purposes.<img>
objects<img>
files are properly optimizedLCP clocks the moment the biggest text block or image visible in the viewport finishes rendering. Simple.
Google recognizes a handful of candidates for LCP:
<img>
elements<image>
inside <svg>
<video>
poster imagesbackground-image: url()
from CSS1. <img> and <video poster>
These are the fastest because the browser’s preload scanner can detect them early—even before layout. For most websites, using a hero image as an <img> or a static splash frame with poster
is the most effective route.
1. Background-image: url()
These are the slowest. Why? Because CSS-based resources don’t load until the browser parses the DOM node, which may be blocked by sync scripts or layout delays. The preload scanner won’t see them, and you’re guaranteed a late LCP.
It doesn’t matter if you’re delaying or deferring scripts or stylesheets. The browser still has to read top-to-bottom and by the time it hits your background image, it might be 100 nodes down the page.
If you’re using it as a CSS element attached to a stylesheet, it then has to read that, too.
2. Text Only
Yeah, sorry, you aren’t bypassing FCP with text only. In fact, sometimes long blocks of text above the fold can be worst of all.
Why? Because if you’re using a custom font that needs to load and that adds time to a complete rendering, and might even showcase layout shifts (which dings your score further).
3. <image> in <svg>
Chrome (≤101) used to misreport this candidate, sometimes flagging a much smaller element as the LCP. Though fixed in Chrome 102, <image> in <svg> is still hidden from the preload scanner, delaying discovery and rendering.
We built test cases to measure the performance of each candidate in controlled conditions:
<img src="lcp.jpg">
: Fastest. Discovered immediately.<video poster="lcp.jpg">
: Ties with <img>. Efficient and predictable.<svg><image href="lcp.jpg"></image></svg>
: Slower, hidden from preload scanner. Buggy in older Chrome.<div style="background-image: none;" data-bg="lcp.jpg">
: Slowest. Discovery delayed.Even with the right candidate, it’s easy to mess things up. Avoid these common mistakes:
loading="lazy"
prevents the preload scanner from seeing your hero image. Don’t do it.preconnect
can’t fix the overhead.And very importantly:
The king of LCP is far and beyond the <img>
.
To make it even faster, you need to preload that asset right after the <head>
opens.
And a reminder, you cannot preload background images.
It’s simple —
<img>
For Theme Builders, the following are the biggest culprits when it comes to using background images for full-or-most-screen hero sections:
Use an <img>
instead of a background image.
This might take a bit of CSS to render properly, but we believe in you.
We write a lot about how Static WordPress is faster, period.
However, it doesn’t fool Google in terms of HTML optimization practices.
We offer several Performance Features that help:
All of this happens during a Static push without reliance on third-party Plugins.