How to measure First Screen Paint?

76 Views Asked by At

Web Vitals comes with two well known metrics: FCP and LCP. It is good ideas to measure paint time. But I have different problem.

I have to implement a metric which describes when the first screen completely loaded within viewport. It means that I need to measure the least timing when:

either body height larger than viewport height, or document completed

My first attempt to implement this was following:

Sets an interval which checks this condition every 200ms. Pseudo code:

setInterval(() => {
  if (document.body.clientHeight > window.innerHeight || document.readyState === 'complete') {
    resolve(); // commit!
  }
}, 200);

But this way has two major issues:

  1. it's inaccurate due to 200ms window;
  2. it's inaccurate due to setInterval does not promise to perform a callback at the specified time.

The second way is to use MutationObserver. Pseudo code:

new MutationObserver(() => {
  if (document.body.clientHeight > window.innerHeight || document.readyState === 'complete') {
    resolve(); // commit!
  }
}).observe(document.body, {attributes: false, childList: true, subtree: true});

It's fine and solves that issues, but there is a huge problem. In this way need to recalculate window height on each HTML commit. There is a problem for pages with large amount of HTML-chunks which comes from the server.

And this solutions become irrelevant to measure the first screen paint when resources for the first paints and first scripts execution are very important.

My question is how to measure the First Screen Paint metric with minimal performance costs and sufficient accuracy?

Maybe there is an API which I just don't know about :)

1

There are 1 best solutions below

4
Barry Pollard On

The only metric to measure the "first screen" is Speed Index, but it's a complex, resource-intensive, complex metric to calculate outside of the lab and is not recommended to measure in the field.

Other than that websites don't really work on screenfuls ("there is no fold"), nor are they static as new content is often continually loaded throughout (think social media feeds update, ads loading, notifications going off) so there is not real measure on when the page has stopped updating. Additionally, if the "first page" is fully rendered and then a small notification icon changes, or an ad plays, or a carousel automatically moves then when should this be measured.

I also don't understand why you think measuring client height/width is a good measure of this. Just because some content beneath the screen exists doesn't mean the content above the screen is complete.

This is why metrics have instead moved from First Paint (FP - which measures any paints), First Contentful Paint (FCP - which excludes non-contentful paints like just background colours), and Largest Contentful Paint (LCP - which tries to be a measure of what is the largest, and so presumably the most important, content).

If you want to measure when specific content is rendered, then Element Timing (which is what LCP is based on) is a good API to look at. The difference with FCP and LCP being that you, as a page owner, can decide which element to measure.