How usefulangle.com Improved Its Largest Contentful Paint (LCP)

javascript
Published on December 21, 2020

While preparing usefulangle.com for Google Search May 2021 changes (where LCP, CLS & FID would be a signaling factor for page rank), I was having a hard time improving the LCP (Largest Contentful Paint).

The fact that LCP may change over several stages, probably makes it the trickiest of all web vital metrics.

Mostly the cause of a high LCP is a slow server response time. If the website uses a CDN to serve content, then probably it would not face the issue of a high LCP.

However usefulangle.com does not use a CDN (yet). I had to figure out a way to improve the LCP with the assumption that server response time is going to be slow.

Before the Improvements

I tried optimizing the site by making the CSS inline, better management of third-party scripts, giving width & height attributes to <img> tags etc.

FID & CLS improved but somehow LCP was always around 3 seconds.

Even though the page score looks good here, however it cannot be guaranteed when the website has a large number of page views per day.

A Bit About LCP

The Largest Contentful Paint (LCP) metric gives the render time of the largest image or text block in the viewport. As a webpage loads resources in stages, it is possible that the largest element on the page may change — so LCP may change as well.

In usefulangle.com, the high LCP was attributed to the hero image which was the largest element on the page. It took some time for me to realize that if I made the size of the heading text (<h1> tag) greater than the size of the image, LCP would be lowered. This is because the heading text would become the largest element on page, and obviously its render time would be much lower than the image (which needs to be fetched, decoded & then rendered).

Improvement 1 — Removing Google Fonts

I realized I had to remove Google Fonts to maximize performance, especially when there was no serving CDN. Fonts first needs to be fetched, and when they are fetched they cause change in layout size, and a paint is triggered. A re-paint may increase LCP.

(This was a turning point — I had been using Google Fonts for all my web projects since the very beginning. Not using Google Fonts seemed strange.)

To prevent fetching a font resource, I decided to use the system font. This is the default font of the operating system. The default font of operating system is obviously chosen with care, so I decided to rely on it.

body {
	font-family: Ubuntu,"Segoe UI",system-ui,-apple-system,sans-serif;
}

Improvement 2 — Setting Size of Text Block Greater Than the Hero Image

Originally the height of the hero image was set to 250px. Now I reduced it to 150px. The image was using the object-fit: cover CSS property, so this ensures that image is not squished at least.

I then increased the font size of the heading text.

Both these changes ensured that the heading text becomes the largest element in the viewport. Furthermore no fonts need to be fetched to render it.

Results

Results turned out to be great! LCP was reduced to under 1 second. Page score became 100.

Other Useful Resources

In this Tutorial