DEV Community

Cover image for How to optimize for Largest Contentful Paint (LCP)?
Omar Moataz Attia
Omar Moataz Attia

Posted on

How to optimize for Largest Contentful Paint (LCP)?

The answer, as with anything, is it depends! I know that's a
bit of a sit on the fence kind of answer but let's dive a bit deeper into it to figure out at least what to look for.

First, we need to be able to identify what the LCP element is. For that, we have 2 options: Local Lighthouse using chrome dev tools and Page Speed Insights (PSI) which allows you to do the same thing only for live or preproduction environments we might have. Each one has their use case. Local Lighthouse is useful when you're trying to verify that a fix actually works or that your build is not going to introduce a performance regression. PSI is useful if you want to figure out what your current performance is using a live URL.

Note: PSI also runs on the lighthouse engine, the difference is that the performance checks are run by Google servers so the runs are not dependent on your machine's performance unlike running lighthouse locally. This means that PSI scores tend to be more accurate because they're produced using a consistent synthetic environment.

If you're interested in all the different ways to run lighthouse, here's the perfect article for you by the folks at Google.

Now that we've figured out how to run a lighthouse performance test, let's try our hand at actually analyzing the results which, in this case, is really easy. If you scroll a bit through the lighthouse results, you'll easily be able to find the LCP element for a particular page like so:

PSI performance results for dev.to homepage

Now that we've figured that out, how can we fix it? Well, we can first take a look at whether the LCP element is a text or image element because our solutions would definitely differ in each case but one thing is consistent with LCP, the less render-blocking JS or CSS you're loading, the better so it's useful to try and figure out what's being bundled and whether we can reduce it. (more on that later)

If the LCP element is an image, we can try rendering a smaller image for responsive formats because, usually, phones don't need as high of an image resolution as desktop so we need to serve smaller images based on device type. We can also serve images in progressive formats like WebP which can provide higher fidelity at lower cost than legacy formats like JPG and PNG. If you're worried about browser support for this format, you can check caniuse for compatibility with different browsers.

What if the LCP element is a text element? Well, we might want to look at how our font is being rendered. You see, if you're using a custom font, and the likelihood is that you probably are, you're requesting that font from somewhere which means that you're wasting time where the user doesn't see any text while the font is being fetched. To solve that problem, we need to show the default system font that's available locally first then switch it out for the custom font as soon as it loads. To do that, we can use the CSS font-display property which has 2 options of interest in this case: Block or Swap. In most cases, we should be using swap but if you're interested to learn more, here's a great summary of the trade-offs by Chris Coyer.

In this article, I summarized my thought process when it comes to debugging LCP issues and trying to fix them. This is by no means a definitive guide but rather meant as a starting point for your investigative journey into LCP performance.

Top comments (0)