Largest Contentful Paint

What is the Largest Contentful Paint and why does it matter? Learn how to improve the Largest Contentful Paint

Arjen Karel Core Web Vitals Consultant
Arjen Karel

What is the Largest Contentful Paint?

Largest Contentful Paint (LCP) is one of the three Core Web Vitals metrics. The LCP captures the Loading part of the Core Web Vitals and represents how quickly the main content of a web page is loaded. Specifically, LCP measures the time from when the user initiates loading the page until the largest image or text block is rendered within the viewport.

 Core Web Vitals are a subset of the Google Page Experience. The Core Web Vitals are high-level metrics, designed by Google, to capture the user experience. Three core Web Vitals metrics are measured: Largest Contentful Paint, First Input Delay, and Cumulative Layout Shift. Each of these metrics is automatically assigned a rating of Good, Needs Improvement, or Poor based on the industry standard methodology and testing designed by Google.

You will learn what the Core Web Vitals are and how to measure and improve them.

largest contentful paint

What is the Largest Contentful Paint?

The largest Contentful paint is a largest single element that has content of the type image or text that has been painted on the visible part of the screen. The LCP timing indicates the time in milliseconds between requesting the page and when the largest contentful (DOM) element is displayed on the visible part of the web page (above the fold).

The LCP is chosen because it focused on a visitor's user experience. When the LCP occurs you can assume that a visitor thinks the page is finished (while that may not be the case at all).The LCP was created to answer the question: ' When is the content of a page visible?'.

How to measure the Largest Contentful Paint?

The Largest Contentful Paint (LCP) can be measures with Lab data and Field tools. Both have their advantages and disadvantages.

Measure the Largest Contentful Paint with Lab tools

Lab tools can measure the Largest Contentful Paint. The advantage of using lab tool is that the results are always measured the same way. They are easy to compare. 

Measure the Largest Contentful Paint with Field tools

Field data is the only data that actually matters for the Largest Contention Paint.  Google uses real user metrics from their CrUX dataset to determine whether of not you pass or fail the Core Web Vitals.

The CrUX dataset is highly anonymized. This means that the CrUX data does not give you much detail on a page or device level. That is Why RUM monitoring is a great alternative for the CrUX data. 

lcp doredash rum

What is a good LCP score?

A good LCP score is anything below a 0 and 2.5 seconds. If your LCP score is between 2.5 and 4 seconds it needs improvement. Any LCP score above 4 seconds is considered poor. To pass the Core Web Vitals for the Largest Contentful Paint at least 75% of your visitors need to have a 'good' LCP score.

How to improve the LCP

When a page renders a lot might happen. Styles, scripts, fonts and images usually compete for network and CPU resources. Everything that happens either network or CPU wise before the LCP element has been painted will affect the LCP.

lcp breakdown schema

It makes a lot of sense to break down 'everything that can happen ' before the Largest Contentful Paint into 4 categories:

  1. Time to first byte
  2. Resource load delay
  3. Resource load time
  4. Element render delay

Each of those categories can be optimized to improve the Largest Contentful Paint

1. Improve the Time to first byte

The time to first byte is the time between the start of the page request and the first byte that has been received. Time to First Byte (TTFB) is a foundational metric. This means that any improvement on this metric will immediately reflect in a  better LCP!  Improving the time to first byte is a great idea regardless of the Largest Contentful Paint benefits. 

Keep in mind: every resource has its own Time To First Byte. We are talking about the TTFB of the original HTML request

  1. Server side caching. Server side caching is one of the most effective ways to improve the TTFB. You can cache full pages, parts of the page, objects in memory or common database queries.
  2. Set up client side caching. Client side caching will improve (or rather eliminate) the TTFB for repeat visitors. BE careful though because with client side caching enabled visitors might see an older, cached version of a webpage that might even be be outdated.
  3. Consider using a CDN. A CDN stands between a visitor and the webserver . A CDN typically does not improve TTFB directly but since a CDN network is typically configured much much better then your average hosting server it might even give a small advantage in TTFB.
  4. Consider setting up static page caching. If you do use a CDN try to unlock the power of pull page edge caching. This means that you entire page is cached on CDN edge servers all over the world and can be served much faster then through your own origin server.
  5. Minimize your html. Every byte that you leave out will improve the TTFB. So enable gzip compression for your HTML, minify your HTML and be careful with inline resources like SVG's or too much structured data like JDON-ld.
  6. Set up your server correctly. This might be a bit technical but it setting up your web server for speed (HTTP/3, connection resumption, fast SSL ciphers etc)

Improve resource load delay

The resource load delay is the time between the Time to First Byte and when the browser starts loading the LCP resource. This only applies when an LCP element is not a text element.

The resource load delay is one of the most common issues that I have to fix. Consider this scenario: A slow wordpress website was 'fixed' with WP Rocket. The LCP image is now automatically lazy loaded. This means that the image will only be queued after all the stylesheets and scripts have loaded. On a slow mobile device this can easily take 7 or 8 seconds.

  1. Prioritize your LCP element with resource hints. The most effective way to eliminate resource load delay is to prioritize it with resource hints. There are 3 ways of doing this. 
    1. The fastest way is to use 103-early-resource hints.
    2. A good alternative is preloading the LCP images
    3. The easiest but slightly slower way is to set fetchpriority="high" on the LCP element
  2. Avoid unnecessary resource hints. Resource hints are great ut when you prioritize the 'wrong' resources they will compete with the more important resources and slow down the Largest Contentful Paint  
  3. Avoid background images. Background images, that are linked in a stylesheet, will only be enqueued after the stylesheet has been downloaded and rendered.
  4. Make sure your LCP element can be discovered by the preload scanner. The preload scanner is a small scanner that quickly scans your page for easy-to-discover, important elements. Lazy loaded images with the data-src attribute are not recognized by the preload scanner and will only be queued by the DOM Scanner. The DOM scanner will be blocked by StyleSheets and JavaScripts while the preload scanner is never blocked.
  5. Use font-display:swap or preload your webfonts. If you use webfonts the text elements might render only after the web-font has been downloaded. Web-fonts are only downloaded after they are found in the render tree (after the DOM has been generated and the CSS has been downloaded and parsed). That is why you should always preload important web-fonts and if possible use font-display="swap". The CSS property font-display:swap tells the browser that it is ok to render the text with a fallback font while the real web-font is being downloaded.

Improve resource load time

The resource load time is the time that it takes the resource to load. 

  1. Load LCP element from your main domain. A common mistake is to load the LCP element from another domain. This will require a whole new connection. It takes a relative long time to set up these new connections.
  2. Consider a CDN. A CDN can cache your static resources like images and serve them from edge servers all over the world that are much closer to the clients location.
  3. Set up client side caching. Client side caching will completely eliminate the resource load time for repeat visitors. Add an expires header to static resources to make sure they are client cacheable.
  4. Use newer, next-gen image formats. If you are still using jpg or png images consider converting these images to the newer WebP of Avif formats. These formats use a much better compression algorithm that will decrease the size of these images considerably. Smaller images mean faster downloading!
  5. Use responsive images. If your images are not responsive your mobile visitors will need to download desktop-sized images. Server smaller images to mobile visitors that will fit in the mobile viewport.
  6. Use HTTP/3. When you use the newest HTTP/2 or HTTP/3 protocol you can benefit from a lot of technical advantages like multiple parallel requests and better error handling. In short: newer HTTP protocols are much faster then the old ones. 

Improve element render delay.

The element render delay is the time between when the browser has finished downloading the resource and the time it starts rendering the element. If the element cannot render immediately this is because the browser is busy. USually this is because it is still downloading or parsing styles or the main thread is blocked by JavaScript.

Improve render delay caused by StyleSheets.

When your LCP element is a text element (uncached) external stylesheet will always cause a render delay. When your LCP element is an image it will only cause a render delay if the Style-sheet downloading and parsing takes longer then the image to load.

  1. Use critical CSS. Critical CSS is a collection of the styles that is needed to render the visible viewport. These styles are placed inline, i the head of the page. The original styles are downloaded in parallel but are not render blocking. When done correctly Critical CSS will eliminate most of the render delay caused by CSS.
  2. Split up large CSS files. In some cases, it can be faster to split up large stylesheets into 2 or 3 separate stylesheets that are downloaded in parallel.
  3. Defer non-critical CSS. If styles are never in the visible viewport it makes sense to defer these stylesheets and load them in parallel.
  4. Minimize StyleSheets. Minimize your stylesheets by removing unused references and unneeded characters like spaces, tabs and newlines.
  5. Make stylesheets Cacheable. For repeat visitors, eliminate the LArgest Contentful Paint render delay completely by serving the CSS files directly from the browsers cache.
  6. Consider using a CDN. I have said it a few times. A well configured CDN will improve resource timing!

Improve render delay caused by JavaScript

  1. Remove unused JavaScript. Most pages have a lot of unused code. You can improve the Core Web Vitals (and not just the Largest Contentful Paint) by removing code that is not needed on the page.
  2. Defer or schedule JavaScript. Deferred JavaScript will download in parallel with the rest of the resources and will be executed at DOMContentReady. 
  3. Break up long tasks. If a script runs before the LCP element has been painted on the screen the main thread will be blocked and the LCP element will not be painted on the screen. That is why it is a great practice to break up code that rungs for long into smaller, more manageable pieces that will 'yield to the main thread'.
  4. Pre-render your content. If your site runs on a JavaScript framework like REACT or Angular consider server side rendering. This will serve a pre-rendered page to the browser. 


Largest Contentful PaintCore Web Vitals Largest Contentful Paint