This feature is well established and works across many devices and browser versions. It’s been available across browsers since April 2021.
* Some parts of this feature may have varying levels of support.
The PerformancePaintTiming interface provides timing information about "paint" (also called "render") operations during web page construction. "Paint" refers to conversion of the render tree to on-screen pixels.
There are two key paint moments this API provides:
A third key paint moment is provided by the LargestContentfulPaint API:
The data this API provides helps you minimize the time that users have to wait before they can see the site's content start to appear. Decreasing the time until these key paint moments make sites feel more responsive, performant, and engaging for your users.
Like other Performance APIs, this API extends PerformanceEntry.
This interface has no properties but it extends the following PerformanceEntry properties by qualifying and constraining the properties as follows:
PerformanceEntry.entryTypeReturns "paint".
PerformanceEntry.nameReturns either "first-paint" or "first-contentful-paint".
PerformanceEntry.startTimeReturns the timestamp when the paint occurred.
PerformanceEntry.durationReturns 0.
This interface has no methods.
Example using a PerformanceObserver, which notifies of new paint performance entries as they are recorded in the browser's performance timeline. Use the buffered option to access entries from before the observer creation.
const observer = new PerformanceObserver((list) => {
list.getEntries().forEach((entry) => {
console.log(
`The time to ${entry.name} was ${entry.startTime} milliseconds.`,
);
// Logs "The time to first-paint was 386.7999999523163 milliseconds."
// Logs "The time to first-contentful-paint was 400.6999999284744 milliseconds."
});
});
observer.observe({ type: "paint", buffered: true });
Example using Performance.getEntriesByType(), which only shows paint performance entries present in the browser's performance timeline at the time you call this method:
const entries = performance.getEntriesByType("paint");
entries.forEach((entry) => {
console.log(`The time to ${entry.name} was ${entry.startTime} milliseconds.`);
// Logs "The time to first-paint was 386.7999999523163 milliseconds."
// Logs "The time to first-contentful-paint was 400.6999999284744 milliseconds."
});
| Specification |
|---|
| Paint Timing> # sec-PerformancePaintTiming> |
| Desktop | Mobile | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android | WebView on iOS | |
PerformancePaintTiming |
60 | 79 | 84 | 47 | 14.1 | 60 | 84 | 44 | 14.5 | 8.0 | 60 | 14.5 |
first-contentful-paint |
116See bug 40066208. |
116See bug 40066208. |
84 |
102See bug 40066208. |
14.1 |
116See bug 40066208. |
84 | 44–78 | 14.5 | 8.0–24.0 | 60–116 | 14.5 |
first-paint |
116See bug 40066208. |
116See bug 40066208. |
No |
102See bug 40066208. |
No |
116See bug 40066208. |
No | 44–78 | No | 8.0–24.0 | 60–116 | No |
paintTime |
No | No | 140 | No | No | No | 140 | No | No | No | No | No |
presentationTime |
No | No | 140 | No | No | No | 140 | No | No | No | No | No |
toJSON |
60 | 79 | 84 | 47 | 14.1 | 60 | 84 | 44 | 14.5 | 8.0 | 60 | 14.5 |
© 2005–2025 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/API/PerformancePaintTiming