Search code examples
javascriptscopelifetimeweb-performance

Extend scope of PerformanceObserver in JS


The PerformanceObserver [1] Interface is used to display web performance metrics such as First Paint (FP), and First Contextual Paint (FCP). It is currently in "Candidate Recommendation Status".

I was reading up on this [2] link, which shows the following code for displaying the FP and the FCP in the console:

const observer = new PerformanceObserver((list) => {
  for (const entry of list.getEntries()) {
    // `entry` is a PerformanceEntry instance.
     console.log(entry.entryType);
     console.log(entry.startTime); // DOMHighResTimeStamp
     console.log(entry.duration); // DOMHighResTimeStamp
   }
 });

 // Start observing the entry types you care about (in this case, paint)
 observer.observe({entryTypes: ['paint']});
 // observer object is destroyed here.

Here arises the problem - I am not interested in reading the values from the console, or logging them through Analytics - I need to store them in an object for further use.

According to this [3] link, the PerformanceObserver instance is implicitly destroyed as soon as the job is done. The ending comments on the link show the bug is fixed, though this is definitely not the case.

Although this line is of interest (in the third link, starting comment) -

Currently if a Performance observer instance is not explicitly kept alive in JS (eg. by attaching to window or long lived object)

which means that the instance can be attached to window or any long-lived object for extending its scope / lifetime. How is this done?


Solution

  • You can store the entries in a global array to use it later

    const globalPerfArray = [];
    const observer = new PerformanceObserver((list) => {
        for (const entry of list.getEntries()) {
            globalPerfArray.push(entry);
        }
    });
    

    if you only observer for 'paint'

    observer.observe({ entryTypes: ['paint'] });
    

    then you will get two entries 'first-paint' and 'first-contentful-paint' just after the pages is loaded. No further entries for Type 'paint' are logged afterwards since this are page loading events.