Wanna see something cool? Check out Angular Spotify 🎧

Improve First Contentful Paint (FCP)

Even though First Contentful Paint (FCP) is not a Core Web Vital, it is still an important metric to measure and improve. The Lighthouse report includes FCP as one of the metrics to measure web performance.

First Contentful Paint

First Contentful Paint (FCP) measures the time from when the user first navigates to the page to when any part of the page’s content is rendered on the screen. Following FCP are other metrics like Largest Contentful Paint (LCP), which is part of the Core Web Vitals. Therefore, improving FCP will also improve LCP.

First Contentful Paint

What is a good FCP score?

To provide a good user experience, sites should strive to have a First Contentful Paint of 1.8 seconds or less. To ensure you’re hitting this target for most of your users, a good threshold to measure is the 75th percentile of page loads, segmented across mobile and desktop devices.

First Contentful Paint

How to Improve FCP

As a quick reminder, the first contentful paint is the time from when the page starts loading until the user sees an indication that the page is going to load. Another way of saying that is we need to respond quickly.

So how do we do that? How do we make sure that we’re responding quickly? Well, let’s conceptually think about our website again.

All websites inherently have:

Website Components

  • A set of servers, hosts, or virtual machines.
  • A set of documents that need to be delivered across the network to your users.

There are a few different parts of this process that can contribute to slowing down the first contentful paint.

Your servers need to be quick. You need to deliver small documents that can be sent efficiently, and the number of hops through the network needs to be as short as possible.

Quick Servers

Quick Servers

So, how do we make sure your server is quick? We need to ensure that your server is sized correctly for what you’re doing. This is the first step in improving it by focusing on your servers.

The specific changes to your servers will depend on what you’re doing and what technology stack you’re using. But essentially, you need to focus on three things:

  • Sized correctly: First, size the hardware, virtual machine, network, or whatever your constraining factors are correctly. Ensure that you have enough overhead in the machines you’ve selected to deliver the content you need.
  • Minimal processing: Second, minimize the processing needed to fulfill the request. For example, if you just need to serve an index.html page to your users, you probably shouldn’t be making calls to your database unless there’s something especially interesting that you need to do.
  • Network bandwidth: Third, the bandwidth to your servers needs to be large enough to fulfill all the requests coming in at once.

Small Documents

Small Documents

There are two major things to consider here: the size of our content and how we compress it.

Content size: How do you deliver as small a payload as possible while still getting the effectiveness you need? This will depend on your application, but if you’re delivering an HTML page, a JavaScript file, or an image, there are certain upper limits on how much you should send. For an HTML document, if you’re sending anything more than 80 or 100k in total size, that’s too much. An image might be 1mb at its upper limit. If you’re sending larger files, you’re sending too much content to be consumed efficiently.

Compression: Even if you’re sending a 100k HTML document, how you compress that document over the wire can greatly improve speed. Most platforms support Gzip compression, and newer web platforms support more advanced compression such as Brotli. The specific compression method will depend on your technology stack, but compressing your documents can greatly reduce the number of bytes sent over the wire.

See the following example of how much you can save by compressing your content. I used curl with the —compressed flag to download the HTML of a website. The original size is 700kb, and the compressed size is 200kb.

Compression

curl  -o /dev/null -s -w "File size: %{size_download} bytes\n" https://jira.trungk18.com/main.js
File size: 756498 bytes

curl -H "Accept-Encoding: gzip" -o /dev/null -s -w "File size: %{size_download} bytes\n" https://jira.trungk18.com/main.js
File size: 212983 bytes

curl -H "Accept-Encoding: br" -o /dev/null -s -w "File size: %{size_download} bytes\n" https://jira.trungk18.com/main.js
File size: 215579 bytes

Short Transmissions

If we take a look at the network, there’s more than one thing happening. There’s where our servers are in your data center, Amazon, Microsoft, Digital Ocean, or wherever you host your content. And there’s a series of network hops in their infrastructure, which you largely don’t control.

On the other side, you have your users, connected to their own ISP or wireless network, with a series of hops to manage that network.

Between them is the infrastructure of the Internet, and this time is something we can control based on where we place our servers and how far they are from our users.

For example, if your servers are on the East Coast of the United States and your user is on the West Coast, the minimum time is 200 milliseconds due to the speed of light and network hardware. Reducing this distance can greatly improve performance.

Short Transmissions

So how do you reduce this distance? The most effective way is to use CDNs.

Short Transmissions

CDNs take the content and place a copy at the edge of each user network, so they can grab it without crossing the Internet. Most CDNs, like CloudFlare and Akamai, do this.

When a user makes a request, the CDN will pick it up, call your server if they don’t already have a copy, cache the response, and serve it to every user who asks for it.

Essentially, we’re doing fewer things by not processing each request across the entire network. This is largely about putting infrastructure in place.

Demo

Putting infrastructure in place is very hard to demo and depends on your infrastructure. For example, compression is mostly supported out of the box on most platforms. Some of my web applications are deployed to Netlify and have Content-Encoding: zstd in the response headers by default without me doing anything.

Netlify Compression

Summary

To improve First Contentful Paint (FCP), you need to focus on the following:

  • Quick servers: Ensure your servers are sized correctly, minimize processing, and have enough network bandwidth.
  • Small documents: Deliver small payloads and compress them effectively.
  • Short transmissions: Use CDNs to reduce the distance between your servers and your users.

References

Published 14 Aug 2023

Read more

 — Measuring Web Performance
 — Angular augmenting native elements
 — Core Web Vitals
 — Upgrading from Angular 12 to 15 in Nx Workspace: A Comprehensive Guide
 — nx:run-commands output not colored