w3c / performance-timeline

Performance Timeline
https://w3c.github.io/performance-timeline/
Other
111 stars 27 forks source link

Using a single observer instance throughout the application lifetime #160

Closed vigneshshanmugam closed 4 years ago

vigneshshanmugam commented 4 years ago

I am using PerformanceObserver to capture some of the new entries like paint, longtask, etc. While its possible to create a new PerformanceObserver every-time and start observing for entry types that we are interested in and get notified for the same.

Isn't ideal to create a single observer for capturing the overall user journey and call observe whenever we are interested in the entries and call disconnect to remove the observer during idle time.

 const po = new PerformanceObserver(list => {
    const entries = list.getEntries()
   // capture these entries as part of current navigation
  })

  /**
   * user clicks on /about page and
   * soft navigation triggers
   */
  po.observe({
    type: 'longtask'
  })
  po.observe({
    type: 'resource',
    buffered: true
  })

  // navigation is completed
  po.disconnect()

Currently if I try to reuse the same observer, we get the below warning on the browser console

The PerformanceObserver has already been called with the entry type 'longtask'.

I might be totally using the observer in a wrong way, would like to know more on which approach is preferred and does creating observer for every navigation including soft/hard wouldn't be a performance issue.

yoavweiss commented 4 years ago

It seems like you called the observer multiple times with 'longtask' as its type.

Looking at https://www.w3.org/TR/performance-timeline-2/#observe-method step 7.3 suggests that you should be allowed to do that and that it should replace the previously registered options with the new ones. Looking at the Chromium code that doesn't seem to be what's happening.

@npm1 - halp?

npm1 commented 4 years ago

Trying to summarize the use case: you're disconnecting the observer and later want to reuse it by calling observe() again, right? I think this is reasonable and there are actually two problems:

  1. As Yoav mentioned, technically you should be able to call observe again with the same type. I've filed https://bugs.chromium.org/p/chromium/issues/detail?id=1052509 for this.
  2. disconnect() seems a bit broken? If you're observing longtask and resource, then call disconnect(), then call observe() again, say only on longtask, then according to the spec you'll be back to observing both! That is, options list is not cleared upon a call to disconnect(). I think it should. This is a spec + implementation bug.
npm1 commented 4 years ago

Ok, I think this is now fixed, so closing this. Feel free to play with Chrome and other browser vendors (if they support 'type' yet?). If a specific one is not working as expected, probably best to file a bug with them directly.

vigneshshanmugam commented 4 years ago

Thanks both for the detailed explanation and also for the fixes.