SEO check

Largest Contentful Paint Test: How to Check and Fix LCP

Find out when the biggest part of your first screen appears, what a good LCP time is, and which fixes move the number fastest.

Free to use 19 min read Updated Oct 2026

Largest contentful paint in one minute

Quick answer: Largest contentful paint (LCP) is the time from the start of navigation until the biggest image or text block in the first screen is painted. Our report wants that moment at 2.5 seconds or sooner on a desktop lab run.

  • Pass: 2.5 seconds or less. A reading of exactly 2.5 still passes.
  • Warning: above 2.5 and up to 4.0 seconds, which earns no score.
  • Fail: above 4.0 seconds, or no LCP value found at all.
  • Fix: find the LCP element, make it load early and small, then remove whatever blocks its first paint.

Check my site free

One honest note before you start. Our report reads a single desktop lab run, while Google judges the 75th percentile of real visits across many devices. The two often disagree.

What is largest contentful paint (LCP)?

Among the three Core Web Vitals, LCP is the one about loading, while cumulative layout shift covers stability and interaction to next paint covers responsiveness. Where the other two describe stability and responsiveness, LCP answers a simpler question: how soon does the main content of this page look ready to a person?

The easiest way to understand the metric is to watch a page load. The browser doesn't know in advance which element is the main one. It reports a new candidate every time something larger than the previous best gets painted, so the final LCP is the last candidate recorded before the page settles. A logo might be the first candidate at 0.6 seconds, a heading the next at 1.1, and a full width photo the last at 3.2. The photo's time is your LCP. Size means the visible area inside the viewport. For an image the browser uses the smaller of the displayed size and the file's own dimensions, so stretching a small file across the screen does not make it count as bigger.

Two other numbers get confused with LCP. First contentful paint (FCP) fires as soon as anything is painted, even a logo, so it can be quick while the main content is still missing. Page load time ends at the load event, which also waits for images below the fold, so it can finish well before or after the hero paints. Our page load time check covers that whole-page number.

Which elements can be the LCP element

Only a short list of element types can become the LCP element. The browser looks at these when it hunts for the largest item in the first screen:

  • Images. A standard img element counts, and so does an image placed inside an inline SVG.
  • Video posters. The poster image of a video element is a candidate, which matters on pages with an autoplaying header clip.
  • CSS background images. An element whose background is loaded through url() counts, although gradients do not.
  • Text blocks. Block level elements that contain text, such as a paragraph or a large heading, can win.

Some things are ignored on purpose. Elements with an opacity of 0, images that stretch across the entire viewport and behave like a backdrop, and very low detail placeholder images are all skipped. That is why a plain text landing page often has a heading as its LCP element: nothing bigger competes with it.

When the LCP value is final

New candidates keep arriving until the visitor taps, scrolls or presses a key, or until the page is unloaded. Browsers stop reporting at that first input because interaction can change what is on screen. Pages opened in a background tab are not reported until the visitor switches to them, so the number reflects what the person actually saw rather than the load.

Our run reads the value right after the load event, while field data keeps collecting candidates until the visitor first taps or scrolls. That, plus slower real devices, is why the two can disagree. A hero that paints at 2.1 seconds in a desktop lab run can take 3.6 seconds on a mid range phone, and both readings are honest.

What is a good largest contentful paint score?

Google publishes three bands for LCP. Assessment is done on the 75th percentile of page loads, which means at least three out of four visits have to be good for a page group to count as good. Mobile and desktop visits are assessed separately, so a fast desktop site can still fail on phones.

RatingLCP timeWhat it meansOur report
Good2.5 s or lessMain content appears quickly for most visitsPass
Needs improvementAbove 2.5 s, up to 4.0 sNoticeable wait, worth fixingWarning, no score
PoorAbove 4.0 sMost visitors wait a long time for the main contentFail

Our report applies the same two numbers to one lab run. It reads the rounded seconds value, and the edge values are spelled out in the rules table below. If you are chasing a good LCP score, leave some headroom below 2.5 seconds in the lab, because real devices are usually slower than a data center browser.

How our largest contentful paint test works

The rule: we load your page in headless Chromium at 1280 by 720, read the start time of the last largest-contentful-paint entry after the load event, round it to two decimals in seconds, and pass it at 2.5 s or less. Above 2.5 s and up to 4.0 s is a warning. Above 4.0 s, or no value, fails.

  • Pass: 2.5 seconds or less in our single desktop run.
  • Warning: above 2.5 and up to 4.0 seconds, no score.
  • Fail: above 4.0 seconds, or no LCP entry recorded.
  • Not tested: mobile throttling, repeat runs, real visitor data, any candidate that paints after the load event, which element was the largest, and how the time splits into the four parts.

Run the full SEO report

What the checker measures

The report opens your URL in headless Chromium on our server, driven by Playwright. The window is a plain 1280 by 720 desktop viewport, with no network throttling, no CPU throttling and no device emulation. It is one run, not an average.

Before any of your page scripts execute, the checker registers a PerformanceObserver for largest-contentful-paint entries with buffering switched on. The start time of the last entry it received becomes your LCP. The page is loaded until the load event, with a 20 second limit, and the value is read straight after that event.

That last detail matters. A candidate that appears after the load event, such as a hero image injected late by a script, is not counted. The milliseconds are converted to seconds and rounded to two decimals before they are compared with the limits and printed in the report.

Pass, warning and fail rules

The rounded seconds value is compared with two limits, and both are written as "above". That is why a reading of exactly 2.5 passes and exactly 4.0 is still only a warning.

Rounded secondsStatusScore effectWhat you see
2.5 or lessPassCounts toward the scoreGreen icon and the seconds
Above 2.5, up to and including 4.0WarningNo pointsAlert box, seconds, How to Fix button
Above 4.0FailNo pointsAlert box, seconds, How to Fix button
Missing or zeroFailNo pointsAlert box with a blank seconds field

Scoring counts passed checks over total checks. A warning is not the worst grade, but it earns no points, so moving from 2.8 seconds to 2.4 raises your report score even though the change feels small.

The missing value rule deserves a word. If the browser never recorded an LCP entry, or recorded a value of zero, for example because the page showed nothing visible to a plain headless browser, the check fails and the seconds field stays blank. Confirm the page renders content without a login or a consent wall, then run the report again. If a firewall or bot challenge sits in front of your site, any lab tool may be measuring that page instead of yours.

What you see in the report

On a pass you get a green icon, the word Congratulations and the measured seconds. On a warning or a fail you get an alert box showing the seconds plus a red How to Fix button, and the same instructions are written out further down this page. The report shows seconds and status only. It does not name the winning element or split the time into its four parts, so the measuring section below is your next step.

Why your number may differ from other tools

Our server sits in a data center with a fast connection, so network time is shorter than what a phone on mobile data sees. The viewport is desktop sized, which can change which element is the largest. Every run also starts with a cold cache, so no image or script saved from an earlier visit helps it along.

Mobile lab tools do the opposite on purpose. They slow the CPU and the network to imitate a mid range handset, so their LCP is usually higher than ours. Treat our number as a quick lab signal that tells you whether something is badly wrong, then confirm it in field data.

Why largest contentful paint matters for SEO

Google recommends good Core Web Vitals for success in Search, and its guidance on page experience says plainly that relevance still comes first. A fast page that fails to answer the query will not beat a slower page that does. Treat LCP as a tiebreaker and a visitor win, not a ranking switch. Google explains its position in the Google Search Central Core Web Vitals documentation. In Search Console, the Core Web Vitals report groups URLs as good, needs improvement or poor from field data, which turns LCP into a concrete to do list.

Visitors judge speed by when the hero appears above the fold, not by when the last tracking pixel fires. A late hero reads as a blank or broken page, and some people leave before it arrives. LCP also carries 25 percent of the Lighthouse performance score in current versions, more than first contentful paint, so a slow LCP drags that score down hard. Lighthouse also weighs total blocking time, speed index and cumulative layout shift (CLS), while interaction to next paint (INP) is a field metric.

LCP is only one of three vitals, and a slow server tends to drag the others down too, so the Core Web Vitals guide is the better place to see how they fit together.

The four parts of a largest contentful paint time

An LCP time is not one lump. It is the sum of four consecutive parts, and knowing which one is biggest tells you where to spend your effort. Google's guidance suggests a healthy split of roughly 40 percent for time to first byte, under 10 percent for resource load delay, roughly 40 percent for resource load duration and under 10 percent for element render delay. Google itself calls these figures guidelines, not strict rules, and they describe a well optimized page rather than the average one.

PartWhat it coversUsual causeFirst fix
Time to first byteNavigation start until the first byte of HTML arrivesSlow hosting, redirects, no page cachePage caching and a nearby server
Resource load delayFirst byte until the browser starts fetching the LCP resourceImage hidden in CSS or script, lazy loadingPut the image in the HTML
Resource load durationDownload time of the LCP image itselfOversized or uncompressed fileResize and use WebP or AVIF
Element render delayResource finished until the element is paintedBlocking CSS or JavaScript, client side renderingDefer scripts, inline critical CSS

Take a page that scores 4.0 seconds. The server wait is 2.4 seconds, the load delay 0.2, the download 1.0 and the render delay 0.4. That puts the server at 60 percent of the total, far above the roughly 40 percent Google recommends, so start with caching and hosting. The download is 25 percent of the total, already below the 40 percent guideline, so even a perfect image would save at most about a second. The server wait is the bigger prize, so fix it first, then come back to the image. Cut that wait to 1.0 second and the page lands at about 2.6 seconds, which is still a warning. The download and the render delay are the next slices to trim, re-testing after each.

If the LCP element is plain text drawn in a system font, there is no resource to download. The two middle parts are close to zero, and the time is simply server response plus render delay. A slow text only page therefore points at the server or at blocking code. If the heading waits on a web font, the font download shows up in the middle parts instead.

How to measure largest contentful paint and find the LCP element

No single tool tells the whole story. You want a lab number, a field number, and the element behind both. Test both a cold and a warm load, and repeat each lab run a few times, since 2.4 once and 2.9 next time is normal.

  1. Start with the free report. Run our free SEO report and note the seconds and the status.
  2. Open PageSpeed Insights. Read the field data panel first, because it shows real visits at the 75th percentile, then scroll to the lab section and the LCP element diagnostic.
  3. Record in Chrome DevTools. In the Performance panel, record a page reload and click the LCP marker to see the element, and open the LCP breakdown or insight in recent DevTools builds to see the four parts.
  4. Check Search Console. The Core Web Vitals report shows which groups of URLs are poor in field data, so you know whether the problem is one page or a whole template.
  5. Log it yourself. Paste the console snippet below if you want the raw start time and the element in plain view.

Field data versus lab data

Field data comes from the Chrome User Experience Report (CrUX), which collects measurements from real Chrome users, and it is what Google uses to judge your site. Lab data comes from a controlled run like ours and is the right tool for debugging, because you can repeat it after every change. WebPageTest is a handy extra for repeat lab runs from different locations. Small or new sites often show no field data yet, so rely on repeated lab runs until it appears.

The two can differ by whole seconds, because real devices and networks are worse than a lab setup and field data keeps recording until the first input. When they disagree, believe the field number for ranking and the lab number for finding causes.

Find the element with a console snippet

Open DevTools on the page, switch to the Console and paste this. It replays the buffered entries and prints the start time and the element of the latest candidate. The LargestContentfulPaint API reference documents every property on the entry.

JavaScript
new PerformanceObserver(function (list) {
  var entries = list.getEntries();
  var last = entries[entries.length - 1];
  console.log('LCP', Math.round(last.startTime) + ' ms', last.element);
}).observe({ type: 'largest-contentful-paint', buffered: true });

Hover over the logged element and Chrome highlights it on the page. For the phone version, turn on the device toolbar and run it again, because the element can differ.

How to improve largest contentful paint, step by step

The rule of thumb is simple: fix the biggest subpart first, change one thing at a time and re-test after each change. Shaving 300 milliseconds off an image does nothing when the server takes two seconds to answer. The advice below follows the same four part model that Google's guide to optimizing LCP describes in more depth.

The order below is the default, and your measured biggest subpart overrides it:

  1. Find the biggest part. Open the LCP breakdown in Chrome DevTools and note which of the four slices holds the most seconds.
  2. Fix server time. Check time to first byte in PageSpeed Insights. If it is well above 40 percent of the total, caching and redirects come first.
  3. Make the image discoverable. View the page source and search for the hero file name. If it is missing there, the browser cannot start the download early.
  4. Shrink it. Compare the downloaded file size in the DevTools Network tab with the size the image occupies on screen.
  5. Clear blocking work. Look at what loads in the head before the hero paints.

Cut server response time (TTFB)

A good time to first byte is around 800 milliseconds or less. Switch on full page caching so the server stops rebuilding the same HTML for every visit, remove redirect chains such as http to https to www, and consider faster hosting or a region closer to your audience. Our explainer on hosting speed and rankings shows what to look for.

A CDN can also cache the HTML itself at the edge, not just images. Our CDN usage test tells you whether one is already in front of your site.

Make the LCP resource discoverable early

Put the main image in the initial HTML as a normal img element, not injected by a script and not set as a CSS background image. Give that one image fetchpriority="high" and never loading="lazy".

When the hero is genuinely only reachable through CSS or script, add a preload link so the browser fetches it during the first parse. Preload sparingly, because ten preloads mean the LCP image competes with nine others.

Here is the markup to aim for on a hero image found in the HTML:

HTML
<img src="/img/hero-1200.webp"
     srcset="/img/hero-600.webp 600w, /img/hero-1200.webp 1200w, /img/hero-1800.webp 1800w"
     sizes="(min-width: 1024px) 1200px, 100vw"
     width="1200" height="600"
     fetchpriority="high"
     alt="Team reviewing a site audit">

And this is the preload for a hero that only appears through CSS or script:

HTML
<link rel="preload" as="image"
      href="/img/hero-1200.webp"
      imagesrcset="/img/hero-600.webp 600w, /img/hero-1200.webp 1200w, /img/hero-1800.webp 1800w"
      imagesizes="(min-width: 1024px) 1200px, 100vw"
      fetchpriority="high">

For a CSS background, set href to the exact URL the stylesheet requests. Use imagesrcset and imagesizes only when the same hero is also an img with srcset, and keep them identical to it. If they differ, the browser may download two files and delay the element you are speeding up.

Shrink the LCP image

Serve the pixel size the screen needs with responsive images, meaning srcset and sizes, so a phone never downloads the 2400 pixel desktop version. Convert to WebP or AVIF and compress the result; our free image compressor and WebP converter do both in the browser, and the modern image formats check shows which files on your page still ship as heavy JPEG or PNG. An image CDN that resizes on request achieves the same without manual exports.

Remove render blocking work

Inline the small amount of critical CSS the first screen needs, then load the rest without blocking. Add defer to scripts that depend on the DOM or on each other, and use async only for independent scripts such as an analytics tag, because async scripts run in whatever order they arrive. Trim third party tags that run before the hero. The render blocking resources guide lists what to look for.

Fix text and font based LCP

When the heading is the LCP element, a web font can hold it back. Use font-display: swap or optional, subset the font to the characters you use, and preload the one file the heading needs. A font preload must carry the crossorigin attribute, even for fonts on your own domain, or the browser fetches the file twice. For the hero heading text specifically, a system font stack is a legitimate choice, and it costs nothing to download.

Avoid client side rendering for the hero

If the first screen is built in the browser after a large JavaScript bundle runs, the element render delay balloons. A page that ships only a bare <div id="root"></div> has no LCP candidate until the bundle has run, so all of that time lands in the render delay. Use server side rendering, or prerender the first screen, so the hero exists in the HTML.

Re-test after every change

Run the free report again after each single change and compare the seconds, so you know which edit helped. If two changes go live together, you won't know which one earned the drop. Field data lags weeks behind your edits, so give it time before you judge.

Largest contentful paint fixes for WordPress, Shopify and custom sites

Platforms put different levers within reach. Check the rendered HTML for the hero image tag rather than trusting the settings screen.

WordPress

WordPress 6.3 and later adds fetchpriority="high" to the first large image automatically, and the pixel minimum can be changed with the wp_min_priority_img_pixels filter. A hero set as a CSS background does not get it, so check the output. Use a page cache, pick one image optimization approach, and avoid sliders on the first screen.

Shopify

The image_tag Liquid filter has a preload option that sends a preload hint in the response header. It also passes extra attributes through, so give the hero loading: 'eager' and fetchpriority: 'high'. Themes differ, so check the generated markup in view source to confirm the fetchpriority attribute actually appears on the img tag.

HTML
{{ section.settings.hero | image_url: width: 1500
  | image_tag: preload: true, loading: 'eager', fetchpriority: 'high',
    widths: '600, 900, 1200, 1500', sizes: '100vw' }}

Replace section.settings.hero with the image object your theme section already uses. The preload: true option only sends the header and leaves the img tag alone, which is why loading and fetchpriority are passed separately.

Custom or static sites

Open the layout or page template, find the hero img, add fetchpriority="high" plus the width and height, delete any loading="lazy" on it and serve a modern format at the right widths. No plugin rewrites your tags on a static site, so view the live source once after deploying to confirm the browser gets exactly what you wrote.

Common largest contentful paint mistakes

Lazy loading the hero image is the classic one. It tells the browser to wait before fetching the single download that matters most, and the delay lands directly on your LCP. A close second is setting the hero as a CSS background, because the browser then discovers it only after the stylesheet is parsed.

Sliders and carousels cause trouble when they wait for script before showing the first slide, which pushes the render delay up. Serving a desktop sized image to every phone, or skipping compression on a hero photo, inflates the load duration.

A cookie banner or large overlay can also become the LCP element, and then the fix is to shrink it. Two more traps are about honesty rather than technique. Tuning only the lab number while field data stays slow improves the report, not the visit. And removing the hero image to pass is a worse page that happens to score better.

Largest contentful paint checklist

  • Element identified. You know which element is the LCP element and have checked it in the rendered HTML.
  • Priority set. The hero image has fetchpriority high and no lazy loading.
  • Image trimmed. It is sized for the screen, compressed and served as WebP or AVIF.
  • Server quick. Caching is on and redirects are trimmed.
  • Nothing blocking. No render blocking script or style sits ahead of the first screen.
  • Verified twice. You re-ran the report and checked field data after a few weeks.

How to Fix

The short version, the same steps you see when you click How to Fix in your report.

Why this fails: the biggest image or text block in your first screen was painted later than 2.5 seconds after navigation started. Between 2.5 and 4.0 seconds is a warning, and anything above 4.0 seconds is a fail. If the seconds value is blank, no largest element was detected, so confirm the page shows visible content to a plain headless browser and run the report again.

How to fix it: first find the LCP element with the PageSpeed Insights diagnostic or the Chrome DevTools Performance panel. It is usually the hero image or the main heading. Then work through these steps in order.

  1. Speed up the server by turning on full page caching and removing redirect chains.
  2. Put the hero image in the HTML itself, add fetchpriority high and remove any lazy loading from it.
  3. Resize the image to the displayed size, compress it and export it as WebP or AVIF.
  4. Add defer to scripts that block the first paint, load non-critical CSS later, and inline only the small critical CSS.
  5. Keep the hero out of client side rendering so it exists in the server response.

Hero image in the HTML:

HTML
<img src="/img/hero-1200.webp" width="1200" height="600"
     srcset="/img/hero-600.webp 600w, /img/hero-1200.webp 1200w"
     sizes="100vw" fetchpriority="high" alt="Describe the hero">

If the hero is only discovered through CSS or script, add this preload as well:

HTML
<link rel="preload" as="image" href="/img/hero-1200.webp"
      imagesrcset="/img/hero-600.webp 600w, /img/hero-1200.webp 1200w"
      imagesizes="100vw" fetchpriority="high">

Platform notes:

  • WordPress: view the page source and confirm the hero img has fetchpriority high and no loading lazy. A CSS background never gets it.
  • Shopify: pass loading: 'eager' and fetchpriority: 'high' to image_tag on the hero.
  • Custom or static HTML: add the attributes in the template and serve modern formats.

Re-test: run our free report again and check that the LCP seconds read 2.5 or lower, then confirm in PageSpeed Insights field data after a few weeks. Google explains each part in the Optimize LCP guide on web.dev.

Re-test my website

Frequently Asked Questions

What is a good largest contentful paint score?
A good largest contentful paint is 2.5 seconds or less. Between 2.5 and 4.0 seconds needs improvement, and anything above 4.0 seconds is poor. Google judges these limits at the 75th percentile of real page loads, so most visits must be fast. Our report applies the same two limits to a single lab run of your page.
How is largest contentful paint calculated?
The browser records the paint time of the largest visible image or text block, measured from the start of navigation, and keeps the last candidate it saw before the first user input. That time is the sum of four parts: time to first byte, resource load delay, resource load duration and element render delay.
What is the difference between LCP and first contentful paint?
First contentful paint marks the moment any text or image first appears, while LCP marks when the main content appears. A page can show a logo early and still have a slow LCP because the hero image arrives late. FCP is also reported in Lighthouse, where it carries a smaller weight than LCP.
How do I find my largest contentful paint element?
Open the PageSpeed Insights diagnostics or the Chrome DevTools Performance panel and click the LCP marker, or log the last largest-contentful-paint entry with a small PerformanceObserver snippet, as shown in the measuring section above. Check desktop and mobile separately, because the element that wins can differ between phone and desktop layouts. On a narrow screen a large heading or a banner can become the largest element instead of the photo.
Why is my largest contentful paint score so high?
The usual causes, in rough order, are a slow server response, a hero image that the browser finds late or that is lazy loaded, a large uncompressed image, render blocking CSS or scripts, and client side rendering of the first screen. Look at the biggest of the four subparts first and fix that one before touching the others.
Does lazy loading hurt largest contentful paint?
Yes, when lazy loading is applied to the LCP image, because the browser then waits before it fetches the one file that matters most. Lazy load only images that sit below the fold, and give the hero image fetchpriority high so the browser downloads it early instead of queueing it behind other requests.
How do I reduce largest contentful paint on WordPress?
Turn on page caching, make sure the hero image carries fetchpriority high and is not lazy loaded, then resize and compress it. Trim render blocking plugins, remove unused scripts and avoid sliders on the first screen, since a slider usually waits for JavaScript before it shows anything. Since WordPress 6.3 the first large image gets fetchpriority high automatically, so in many themes your job is mainly to confirm it is not lazy loaded and to fix caching and image size.

See how your site scores right now

Paste your address into the free report, then use the How to Fix button on anything that needs work.

Free to use. Results in under a minute for most sites.