First Contentful Paint

Improve the Core Web Vitals by speeding up the First Contentful Paint

Arjen Karel Core Web Vitals Consultant
Arjen Karel

Fix First Contentful Paint - in short

The First Contentful Paint (FCP) is the moment when a browser draws the first meaningful element on a page for the visitor to see. In other words, it is the moment a browser first renders something on the screen. As such, the FCP is a good way to measure perceived page load speed.

You can improve the FCP by making sure a browser can start rendering without any delay. I’ll explain what that is and how you do this.

Fix first contentful paint

What is the First Contentful Paint (FCP)?

The First Contentful Paint (FCP) is a way to measure loading page speed. You can’t summarize page speed as a point in time, there are actually several moments during the loading process where a visitor might experience the site as loading quickly or slowly. The FCP measures the time difference between requesting the page to when the first meaningful content is rendered on the screen for the first time.

What exactly does that tell you though? It tells you that the FCP is primarily a "user-centric metric" because it says something about the loading speed a visitor experiences. It says something about the user experience. At the FCP moment, you can be sure a visitor actually sees "something" on the screen.

Let's break down the words: 'First','Contentful' and 'Paint'.

  1. First:  By First, of course, we mean the first exact moment something substantial appears on your browser.
  2. Contentful: With contentful we mean an HTML element with content. So not a layout element like a blank element or background color, but rather some text, an image (including background image), SVG or canvas.
  3. Paint: Paint means (more or less) that the browser is ready to put something on the screen. This seems simple but actually it’s the browser’s most complicated task. In order to put something on the screen, a browser must be ready to calculate all characteristics of an element. Below is an example of the rendering process that is required before anything can be added on the screen.

What is a good First Contentful Paint score?

A good FCP score is anything below a 0 and 1.8 seconds. If your FCP score is between 1.8 and 3 seconds it needs improvement. Any FCP score above 3 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' FCP score.

first contentful paint pass fail scores

As always with the Core Web Vitals, a faster First Contentful Paint score is better the a larger one. 

How do you measure your First Contentful Paint (FCP)?

The FCP is measured by Google by gathering data from real users. That data is stored in the CrUX dataset. That data is publicly available through the CrUX APi or Google BigQuery. The FCP can also be measured through so-called lab tests. The most common lab-test is called Lighthouse.

Getting the First Contentful Paint from the CrUX dataset

The First Contentful Paint  can be read from CrUX dataset through the, the CrUX API, or through google BigQuery.

Measuring the First Contentful Paint through Real User Monitoring (RUM) 

RUM Tracking stands for Real User Monitoring. With Real User Monitoring you can track the First Contentful Paint through real user interactions. The advantage of RUM Tracking is that you do not have to wait 28 days for fresh data and the data can be queried and analyzed in far greater detail.

Measuring the FCP in Lighthouse

  1. Open the page – in Chrome – whose FCP you want to measure. Make sure you do this incognito so the plugins won’t bother you and possibly slow down the FCP of your page.
  2. Right-click on the page and select Inspect Element. This way you open the Chrome developer console.
  3. At the top of the console, you’ll see the Lighthouse tab. Click on it. Then under Categories, choose Performance (leave others blank) and choose Mobile under Device.
  4. Now click on Generate Report. Lighthouse will create a speed report of your page. At the top left corner of the report, you’ll see what the FCP of your page is.

This is a screenshot of the Lighthouse report for this this page. The FCP of this page on a mobile device is 0.8 seconds! Not bad right?

Measuring FCP with an online tool

You can also measure the FCP with a number of online tools. The best known are GTMetrix, pingdom and These tools are easy to work with and will give some data about the LCP under spcifical lab circumstances.

Improving the First Contentful Paint

Now that you know what the First Contentful Paint is, we can get to work on making it faster. The idea behind a fast FCP is actually quite simple: making sure a browser can start rendering immediately. Anything that can cause rendering to be delayed will result in a poor FCP score.

Just like with the Largest Contentful Paint the First Contentful Paint can be broken down into 2 or 4 categories:

  1. Time to first byte (TTFB) - The time from when the starts loading the page until when the browser receives the first byte of the HTML. 
  2. Resource load delay - The time between TTFB and when the browser starts loading the FCP resource
  3. Resource load time - The time it takes to load the FCP resource itself.
  4. Element render delay - The time between when the FCP resource finished loading until the LCP element is fully rendered

Speed tip: You can easily eliminate steps 2 & 3 by making sure the LCP element does not require a network resource. In case of a text element consider using font-display:swap. In case of a small image element consider placing the image inline.

This just leaves us with the Time to First Byte and the Element Render delay to optimize.

Below are 14 solutions I often use to improve the FCP. But be careful, using a solution in the wrong place can actually create delays. That's why it's best to consult a pagespeed expert before you start yourself.

1. Fast server response (TTFB)

The TTFB (the time between the request and the first byte the server sends) is always the first step in the rendering process. From that point on, your browser starts multitasking, and impact of further optimizations starts to decline. The HTML code is the only request that directly affects all speed metrics.

The speed at which the HTML code is sent from the server is often measured as the time to first byte (TTFB). It’s important to make this as quick as possible. Often you do this by enabling server side caching.

When it comes to time to first byte, lower is always better. 

You can easily measure the time to first byte yourself. It’s done as follows:

  1. Use the shortcut Ctrl-Shift-I to open the developers console of Google Chrome.
  2. At the top of the console, you'll see a Network tab. Click on it.
  3. Reload the page through Ctrl-R.
  4. You’ll now see all the network requests that Chrome has sent to your server.
  5. Click on the top network request, which is the request for your page itself.
  6. Now you’ll get more information about this network request.  Click on the timing tab at the top of this information to see what the TTFB is for your page.

2. HTTP/3

HTTP/3 is the third version of the HTTP protocol. HTTP/3 solves many of the problems found in the older HTTP/1.1 and HTTP/2 protocols. For example, since HTTP/2, you can send multiple files at the same time through the same connection. HTTP/3 provides a faster initial connection and less trouble from minor network interruptions.

Without going into too much detail, HTTP/3 allows for a significant speed gain, especially on a slower network such as a mobile network. Your network administrator can tell you if your web server is already suited for the faster HTTP/3 protocol.

You can check for yourself whether your website is already using the faster HTTP/3 protocol. Use the shortcut Ctrl-Shift-I to open the network inspector of Google Chrome. Right-click on the table reader and select Protocol. Now reload the page to see what protocol your site is using.

3. Browser Caching

The network connection is often a weak link when it comes to page speed. Wouldn't it be so much easier to skip the network altogether?

When a visitor has been to your site before, you can indicate if and how long the network resources  (for example a stylesheet)  can be stored by the visitor's browser. Every time the visitor needs one of these files again, they pop up from the browser’s cache in no time. As a result, the browser can start rendering much faster and speed up the FCP.

4. Compression

The network speed is in almost all cases a weak link. For a good First Contentful Paint, it’s so important that the files are sent through the network as fast as possible. Compression reduces the number of bytes that must be sent from the server – fewer bytes means less time waiting on a network resource. Compression, in my opinion, is a technique that’s not getting the attention it deserves. Unfortunately, too many webmasters “turn compression on” and then don’t take another look at it anymore. And that’s a shame because it’s just an easy way to make things go just a little bit faster.

here are two popular compression techniques: Gzip and Brotli. Gzip is the most used compression technique but Brotli is quickly catching up. Brotli has been created by Google itself and has 15 to 2-0% better results when it comes to HTML, JavaScript or CSS files. Brotli is, therefore, ideal for the web.

There’s also a difference between dynamic compression and static compression. With dynamic compression you compress the file just before you send it through your web server; with static compression, the compressed file is stored on the server. This is often a much smarter way to compress, but it’s rarely used.

5. Early web-fonts with resource hints

Resource hints initiate a download or network connection before the browser would do so on its own. Some network resources, such as web fonts or images, are only downloaded after the browser is sure it needs to display them.

If you’re sure you need a resource to render the visible part of the site, it’s almost always a good idea to include a “resource hint”. This will make sure the browser starts downloading or connecting to the resource immediately. As a result, the resource is available sooner and the browser can start rendering sooner.

But be careful with resource hints, if you use them incorrectly, they can actually slow down your page.

Early download with "preloading"

<link rel="preload" href="/static/font/opensans600.woff2" as="font" type="font/woff2" crossorigin>

The preload link is one of the most powerful tools in the page speed arsenal. Through the preload link, you download a network resource you’ll need later. This is often a very good idea with fonts, critical scripts and images on the visible part of the site.

Connecting in advance with preconnect

The preconnect link already connects to a server. This is useful when you host files on a third-party server such as a CDN or Google analytics.

<link rel="preconnect" href="">
<link rel="preconnect" href="" crossorigin>

6. Prefetch the next page the next page with prefetch

<link rel="prefetch" href="/page2.html">

With prefetch, you can fetch low priority resources. This is a useful way to fetch resources that you think you’ll need later – when you expect someone to click on the next page link, for example.

7. Avoid redirects

A common mistake is having a redirect chain that is too long. Let me explain: Your site probably runs through a secure connection. When a visitor types in your site, without adding https, he’ll be redirected to the non-secured version of your website. However, if everything is set up right, the visitor will be redirected to the secure website. You can see this in the green example below.

But sometimes the redirection takes place via one or more intermediate steps, as shown in the red example. It’s these intermediate steps that causes the website to run slow, resulting in a poor First Contentful Paint score. Each intermediate step costs extra time, which can quickly add up. So, always make sure you get to the right page within one redirect.

8. Minimize CSS

An external CSS file is always render-blocking. What that means is that a browser normally can’t start displaying content until all stylesheets have been downloaded and analyzed. Therefore, it’s best to keep stylesheets as small as possible. This way you don't have to wait as long for the stylesheet to be downloaded.

Reducing the CSS size with shortcode

One of the ways to reduce the CSS size is by using shortcodes. These are one-liners that allow you to write down the most important properties of a CSS selector in one line.

    font-style: normal;
    font-weight: 400;
    font-stretch: normal;
    font-size: 0.94rem;
    line-height: 1.6;
    font-family: "Segoe UI", "Segoe UI", system-ui, -apple-system, sans-serif;

You can also write it as:

body{font: 400 .94rem/1.6 Segoe UI,Segoe UI,system-ui,-apple-system, sans-serif;}

Reducing the size of CSS further

It's possible to reduce the CSS size even more by merging selectors with a comma,  removing enters and spaces and writing shorter color codes.

  color : #000000;
  color : #000000;
  color : #000000;
  color : #000000;
  color : #000000;

Could be shortened like


9. Critical CSS

We can take CSS one step further by using critical CSS. Critical CSS is a must-have for a fast website and a fast First Contentful Paint.

Critical CSS is a collection of all the selectors (like body, p, h1 etc.) you need to show the visible part of the page. Don't put this critical CSS in a separate stylesheet; instead, add it directly in the <head> of the page. This way you don't have to download a new file and the browser can start rendering at lightning speed. This makes for a faster FCP. The CSS you don’t directly need for the visible part of the page is loaded after the first rendering cycle is completed. To your visitor, the page is already done – no one will notice the new styles still being added in the background..

Critical CSS can be easily generated with our own critical CSS tool. Just paste the URL of your webpage in the tool and we’ll do the rest for you!

10. Defer loading JavaScript

One of the most common reasons for a slow First Contentful Paint is JavaScript. Depending on how you use JavaScript, it can block the rendering of the page. Normally JavaScript is downloaded and executed before the render tree is built. Without the render tree, a browser can't put anything on the screen – this includes the FCP.

We can work around this by postponing JavaScript. You can do this in three ways

Async JavaScript

<script async src="async.js"></script>

By adding the async attribute to a script tag, the buildup of the page is no longer blocked while the JavaScript is being dowloaded. The async attribute indicates that the download and the buildup of the render tree can happen at the same time.

Once the script is executed, the page is blocked. In most cases, thanks to the async attribute, the browser has had enough time to build an important part of the page, with the First Contentful Paint already on the page.

Defer JavaScript

<script defer src="async.js"></script>

The defer attribute works more or less the same as the async attribute. By adding the defer attribute to a script tag, the script may also be downloaded simultaneously to building the page. After all scripts are downloaded, they’re executed in the order they were found in the HTML code. This can also block the display of the page but in many cases the First Contentful Paint is already on the screen.

11. Don’t rely on external resources

External resources, such as external fonts, external images, external stylesheets or external scripts, are a potential bottleneck when it comes to the First Contentful Paint. Since you have no control of the server where the files are hosted, you don't know how fast they will be sent. In addition, you can't use the existing connection to the web server. A new connection to a new server must be set up – and that takes time.

Blocking external resources

No external resources

12. Use the right font format

Fonts deserve extra attention when it comes to the First Contentful Paint. On about 99% of the pages we look at, the FCP element is a text line. When you use external web fonts, you should download these fonts from a server first, which – of course – takes time. 

Recently, web fonts have been getting more attention, and there are more new, faster font formats. The fastest font format at the moment is woff2, followed by woff. Woff2 is supported by every modern browser. 

You can specify the preferred order of your web font in the CSS font-face declaration. You do that as follows:

 @font-face {  
   font-family: 'myFont';  
   font-weight: 400;  
   font-style: normal;  
   font-display: swap;
   unicode-range: U+000-5FF 
   src: local('myFont'),
        url('/fonts/myFont.woff2') format('woff2'),
        url('/fonts/myFont.woff') format('woff');

13. Font display:swap

When using web fonts, the default behavior of these fonts is to not show the text on the page until the font is loaded. This is usually directly at the expense of the First Contenful Paint. 

You can solve this by using the font-display:swap. With this you can choose to show the text on the page anyway, in a font the browser knows, while the webfont is loaded in the background..

Without font-display:swapFOIT met een webfont

With font-display:swapGeen FOIT met een webfont

Read our complete article  Ensure text remains visible during webfont load

14. Minimize the DOM size

A web page consists of HTML. The first thing a browser does is convert the HTML to DOM nodes. That’s a tree structure of HTML elements that is later used to build the render tree with. From the render tree a browser starts rendering; eventually the web page appears on the screen. 

How many DOM nodes (HTML elements) you have and how deep these DOM nodes are in the tree structure determines how complicated it is for a browser to build your page. CSS and JavaScript also take more time to analyze when you have too many DOM nodes. This, again, is all directly at the expense of the FCP.

Solve this by:

  • Lazy load parts of your web page
    To speed up the initial display, consider loading parts of your website, like the footer, via AJAX at a later time.
  • Make use of content-visibility
    The CSS property content-visibility tells a browser to skip style, layout and paint during rendering. It does so just before the element becomes visible.
  •  Split large pages into multiple pages
    The number of DOM nodes can be reduced by splitting large pages into multiple pages.
  •  Implement infinite scroll
    Infinite scrolling is basically lazy loading: when scrolling through repeated elements such as images (pinterest) or large tables of data, infinite scroll can significantly speed up your page.
  • Avoid JavaScript DOM interaction
    Be extra careful with JavaScript when you have a large number of DOM nodes on your page. A command like can then load a large number of DOM nodes, increasing memory usage.
  • Avoid complicated CSS declarations
    Be extra careful with complicated CSS commands with a large number of DOM Nodes. For example, should check the last-child status for every div element on your page.
  • Use web workers to spare your browser's main thread
    Web workers are JavaScript that can run in parallel with your web page. You can give these web workers commands that are executed in the background. When the web worker has executed the command, it passes it on to the original page. The advantage of this is that you can still execute complex JavaScript without the page freezing up.

I help teams pass the Core Web Vitals:

lighthouse 100 score

A slow website is likely to miss out on conversions and revenue. Nearly half of internet searchers don't wait three seconds for a page to load before going to another site. Ask yourself: "Is my site fast enough to convert visitors into customers?"

First Contentful PaintCore Web Vitals First Contentful Paint