1. Introduction
Load is not a single moment in time — it’s an experience that no one metric can fully capture. There are multiple moments during the load experience that can affect whether a user perceives it as "fast" or "slow".First Paint (FP) is the first of these key moments, followed by First Contentful Paint (FCP). These metrics mark the points, immediately after navigation, when the browser renders pixels to the screen. This is important to the user because it answers the question: is it happening?
The primary difference between the two metrics is FP marks the point when the browser renders anything that is visually different from what was on the screen prior to navigation. By contrast, FCP is the point when the browser renders the first bit of content from the DOM, which may be text, an image, SVG, or even a canvas element.
1.1. Usage example
var observer= new PerformanceObserver( function ( list) { var perfEntries= list. getEntries(); for ( var i= 0 ; i< perfEntries. length; i++ ) { // Process entries // report back for analytics and monitoring // ... } }); // register observer for paint timing notifications observer. observe({ entryTypes: [ "paint" ]});
2. Terminology
Paint: the browser has performed a "paint" (or "render") when it has converted the render tree to pixels on the screen. This is formally defined as the when update the rendering happens in event loop processing.
NOTE: The rendering pipeline is very complex, and the timestamp should be the latest timestamp the browser is able to note in this pipeline (best effort). Typically the time at which the frame is submitted to the OS for display is recommended for this API.
First Paint entry contains a DOMHighResTimeStamp
reporting the time when the browser first rendered after navigation. This excludes the default background paint, but includes non-default background paint and the enclosing box of an iframe. This is the first key moment developers care about in page load – when the browser has started to render the page.
First Contentful Paint entry contains a DOMHighResTimeStamp
reporting the time when the browser first rendered any text, image (including background images), non-white canvas or SVG. This excludes any content of iframes, but includes text with pending webfonts. This is the first time users could start consuming page content.
3. The PerformancePaintTiming
interface
[Exposed =Window ]interface :
PerformancePaintTiming PerformanceEntry {};
PerformancePaintTiming
extends the following attributes of PerformanceEntry
interface:
-
The
name
attribute must return aDOMString
for minimal frame attribution. Possible values of name are:-
: for First Paint"first-paint" -
: for First Contentful Paint"first-contentful-paint"
-
-
The
entryType
attribute must return
."paint" -
The
startTime
attribute must return aDOMHighResTimeStamp
of when the paint occured. -
The
duration
attribute must return 0.
NOTE: A user agent implementing PerformancePaintTiming
would need to include
and
in supportedEntryTypes
for Window
contexts.
This allows developers to detect support for paint timing.
4. Processing model
4.1. Reporting paint timing
4.1.1. Mark paint timing
-
Let paintTimestamp be the input timestamp.
-
If this instance of update the rendering is the first paint, then record the timestamp as paintTimestamp and invoke the § 4.1.2 Report paint timing algorithm with two arguments:
and paintTimestamp."first-paint" NOTE: First paint excludes the default background paint, but includes non-default background paint.
-
Otherwise, if this instance of update the rendering is the first contentful paint, then record the timestamp as paintTimestamp and invoke the § 4.1.2 Report paint timing algorithm with two arguments:
and paintTimestamp."first-contentful-paint" NOTE: This paint must include text, image (including background images), non-white canvas or SVG.
-
Otherwise, do nothing and return.
NOTE: A parent frame should not be aware of the paint events from its child iframes, and vice versa. This means that a frame that contains just iframes will have first paint (due to the enclosing boxes of the iframes) but no first contentful paint.
4.1.2. Report paint timing
-
Create a new
PerformancePaintTiming
object newEntry and set its attributes as follows: -
Add the PerformanceEntry newEntry object.
5. Acknowledgements
Special thanks to all the contributors for their technical input and suggestions that led to improvements to this specification.