Photo by Christopher Gower on Unsplash

We Improved Largest Contentful Paint (LCP) by Over 30% Using These Simple Techniques

Atakan Demircioğlu
Jotform Tech
Published in
5 min readJul 2, 2024

--

This post will explain the simple techniques that we applied in Jotform pages to improve our LCP.

Check out these tips to get started on making your website faster and better for everyone!

What is the Largest Contentful Paint (LCP)?

Largest Contentful Paint (LCP) is one of the three Core Web Vitals metrics. It shows how quickly users see the main content of a page.

It measures the time from when the user initiates loading the page until the largest image or text block is rendered within the viewport.

To provide a good user experience, Google recommends that sites should strive to have an LCP of 2.5 seconds or less for at least 75% of page visits.

LCP value should be 2.5 seconds or less

How to measure your LCP

From my experience, the LCP metric is maybe the hardest Core Web Vital metric to improve. It depends on a lot of other parameters for the page. Before trying to improve it, we need to learn how to measure it.

First, we need to know what elements are considered LCP elements. For example, <img>,<image>,<video> and block level elements are considered LCP elements. See more detailed information in Google’s LCP article.

To measure LCP, we can use lab-based tools or local testing. These tools are good for understanding and improving LCP, but they don’t show what actual users are experiencing.

To understand what the real users are experiencing, we need to use real user monitoring (RUM) tools or CrUX reports.

CrUX example

When you check any page with PageSpeed Insights, you’ll see the CrUX data at the top. This information can give you an idea about what your users are experiencing.

In the lab-based tools part, you can use a tool like Lighthouse. You can use it locally or you can check it with PageSpeed Insights. But don’t forget that the most important thing is what your users are experiencing. The users might not have great devices and healthy internet connections.

Field tools

Lab tools

Sub-parts of LCP

Optimal sub-parts of LCP

For a better understanding of LCP, you need to check its sub-parts.

Here are some ideal percentages for sub-parts:

  • TTFB (~40%)
  • Resource load delay (<10%)
  • Resource load duration (~40%)
  • Element render delay (<10%)

The percentages above are the ideal breakdown of these sub-parts. It is not a strict rule, but you should try to stay under 2.5s.

Here are some tips for reaching these percentages.

Time to first byte (TTFB)

  • Hosting is important.
  • Optimize your backend if needed.
  • Using CDN is a great choice.
  • If possible, you can use cached content.
  • Avoid page redirects.

Resource load delay

  • Avoid JavaScript-generated LCP elements.
  • Preload images.
  • Avoid lazy-loading LCP resources.
  • Leverage fetchpriority attribute.

Resource load time

  • Reduce the size of the resource.
  • Use CDN.
  • Use new image types like WebP and AVIF.

Element render delay

  • Reduce the render-blocking stylesheets.
  • If possible, inline the render-blocking stylesheets (consider using critical CSS).
  • Defer or inline render-blocking JavaScript.
  • Break up long tasks (also important for Interaction to Next Paint, or INP).

How to improve LCP

We talked about sub-parts of LCP. In this section, we will try to improve LCP for better UX.

First, let’s divide this part into two sections: text-based LCP and image-based LCP.

Text-based LCP is generally better than image-based LCP because you do not need to load an image from your server.

Let’s start with a typical example.

Typical LCP example

In this example, we can see the LCP resource is blocked. For an optimized page, we need to start loading the LCP resource as fast as possible.

Preload

To provide this, we can preload the LCP image with a high fetchpriority.

<link rel="preload" fetchpriority="high" as="image" href="ex.webp">

Never lazy-load your LCP

Lazy-loading your LCP image is a big anti-pattern. If you lazy load your LCP image, you will cause an unnecessary resource load delay.

Reduce the TTFB

The main goal is to get the initial HTML as fast as possible. To do this, you can use caching strategies like file cache.

Don’t forget that adding a new cache layer will increase the complexity of your system because you’ll need to consider efficient cache invalidation strategies.

Use modern image formats

To reduce resource load duration, we can use modern image formats, such as WebP or AVIF. By using the new image formats, you can decrease the resource sizes.

While using the new image formats, you need to consider the browser availability. You can check the picture element for dealing with this problem.

Best practices for fonts

Fonts are generally problematic. If you use multiple fonts, it can slow down text-based LCP.

You can use the WOFF2 font format. WOFF 2.0’s internal compression uses Brotli and offers up to 30% better compression than WOFF.

If you are using multiple font variants, you can serve the critical font variants first and you can download the other variants later.

You can preconnect to third-party origins if you use them:

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

You can inline the fonts (if you don’t have a lot of different fonts):

<head>
<style>
@font-face {
font-family: "Any font";
src: url("/fonts/any-font.woff2") format("woff2");
}
</style>
</head>

Eliminate element render delay

If the rendering is blocked for some reason, the LCP element can’t render immediately after the load process.

In general, this is due to synchronous scripts or long tasks.

Long tasks are another problematic thing for INP.

To solve this problem, you need to reduce or inline the render-blocking items.

First, try to remove unused CSS and, if possible, use critical CSS and defer the non-critical CSS. Also minifying and compressing CSS is always good.

Never add synchronous scripts. Use async or defer. If it is a small script, you can just inline it.

Summary

  • Don’t lazy load your LCP image
  • Use efficient cache strategies for better TTFB
  • Use modern image formats
  • Use CDN
  • Check out fetchpriority, preloading
  • For efficient lazy loading, you can check lazy-sizes or check native lazy loading

Resources

--

--

Passionate about blogging and sharing insights on tech, web development, and beyond. Join me on this digital journey! 🚀