How to properly measure how fast a web page starts to display its content? Several Web performance metrics exist to answer this question, including First Paint, Start Render and one of the newest: First Contentful Paint (FCP). How does FCP stand out, what are its limitations? Let’s dive into the metrics that measure the browser’s early rendering of web pages.
After a click or any other navigation action, a user can only perceive a page is loading if some content has started to be rendered. How do we know the moment this rendering starts? One of the simplest ways of finding when the browser first renders something after navigation is to ask the browser itself. This is called “First Paint”, and one of the earliest web performance metric.
First Paint, however, can be misleading: the “paint” is from the browser perspective, not the user’s. And a browser can perform a paint that is not visible to a user. For example, if an element is rendered with the same background as the default background, First Paint is triggered all the same.
Using First Paint to track the performance of your page does not guarantee you’re tracking when something is displayed for your visitors.
How can we focus on what makes sense to a visitor? That’s the question the First Contentful Paint is trying to answer. According to the Paint Timing specification:
FCP is the point when the browser renders the first bit of content from the Document Object Model (DOM), which may be text, an image, SVG, or even a canvas element.
Paint Timing 1
Editor’s Draft, 13 June 2019
As for First Paint, the browser returns the information when processing the rendering of web elements, but it additionally checks the element type (text, image, SVG or a canvas).
First Contentful Paint can be found in Dareboost, WebPageTest or in Google services like Lighthouse or Chrome UX Report which data is used in PageSpeed Insights. For now, FCP is only available on Chrome and Opera. Firefox considers to support it as well.
Here’s how you can get First Contentful Paint from Chrome DevTools:
let fcp = performance.getEntriesByName(``"first-contentful-paint"``).startTime;
Unfortunately, FCP also has a few limitations.
First, it doesn’t take iframes into account, which can be an issue if your main content is relying on an iframe to be loaded (but that’s definitely an edge case to be avoided).
Secondly, FCP can be biased by a text node waiting for a pending web font to be rendered. In the following example, we would presume the FCP to be fired around 900 ms, as we don’t see any content before that:
The actual FCP value is around 600 ms because that’s the time the text node is first rendered by the browser even if the font is not loaded yet, so the text stays “blank” (invisible) for a while. This phenomenon is called Flash Of Invisible Text (FOIT).
To avoid that behavior on your websites, make sure that you’re using the @font-face CSS directive with a non-default value for the
font-display descriptor. If you’re using Google Fonts, please note that the service now encourages its users to use
font-display:swap value. Make sure that your Google Fonts import declaration specifies a value for the “display” parameter in the URL query.
<link href="https://fonts.googleapis.com/css?family=Caveat&display=swap" rel="stylesheet">
One of the main limitations you may be facing with First Contentful Paint is the metric is not bound to the viewport. Wherever is the piece of content displayed, it will trigger FCP, even if the content is not above-the-fold, and thus not visible for a visitor.
To really track the time at which we’re sure there is something displayed and visible for the user, we have to use another metric: Start Render. The Start Render algorithm is based on video analysis of the page loading, looking for the first altered pixel in the viewport.
Even if Start Render will trigger regardless of content type (as the First Paint), it’s a great way to track the time when a user can perceive that the page is loading, while avoiding to track browser-related, “technical”, paints.
Start Render is only available through Synthetic Monitoring tools because a video analysis is required, whereas FCP and First Paint can be directly requested from the browser, making them usable in Real User Monitoring (RUM) as well.
In a nutshell:
- First Paint
- The first paint action of the browser, from the browser own perspective. Not necessarily visible from a human.
- First Contentful Paint
- The first paint action of the browser, from the browser own perspective, concerning a text, an image, an SVG or a Canvas. Iframes are excluded, and text can be painted but still not visible (because of a webfont still being loaded, or outside of the viewport).
- Start Render
- Something is visible by the user in the viewport. Whatever it is, even if it’s only a background.
With Dareboost, you can measure and monitor these metrics very easily. We’re advising to focus on one of them only, and we would suggest the Start Render as it’s the one with the fewer edge cases.
If you’re not already one of our amazing customers, do not wait anymore to ask for a trial on our Synthetic Monitoring Service.
Top comments (2)
Nice overview! I'd like to see a movement towards more user-centric paint metrics. FCP was a step in the right direction but I think we can do better. Largest Contentful Paint (LCP) looks promising: web.dev/largest-contentful-paint
LCP is promising for advanced needs.
However, I think it's missing the point by focusing on one element. Several adjacent elements painted almost simultaneously are not considered to be the same visual element, whereas for a user, they are (first Gestalt law, regarding proximity).
In addition, the metric is complex to implement as, for example, every image needs to have a
Timing-Allow-OriginHTTP header. The server configuration required for that will only be achieved by people who are already involved in Web Performance.
The Start Render is much easier to evaluate and can be collected on any public page right now without any implementation costs. Much easier to compare your web performance to others.