Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PerformanceObserver developer / RUM friendliness #79

Closed
nicjansma opened this issue May 31, 2017 · 6 comments
Closed

PerformanceObserver developer / RUM friendliness #79

nicjansma opened this issue May 31, 2017 · 6 comments

Comments

@nicjansma
Copy link

Hi everyone,

As I've been pondering how we're going to use PerformanceObserver to capture things for Boomerang, I wanted to share some thoughts I had on PerformanceObserver versus the PerformanceTimeline.

Part of the reason I'm bringing this up is that we're making improvements to PerformanceObserver to have it buffer-until-onload as a solution to avoid maintaining a global buffer like the PerformanceTimeline does. I'm worried that the group is leaning toward the PerformanceTimeline going away, deprecating it, or having new specs not support it (e.g. LongTasks).

(I totally get the performance reasons to switch to the observer model, so all of these observations are just on the downsides)

So I would like to share some ideas why, as a developer, and similarly for RUM, getting performance data from PerformanceTimeline is more friendly than observing via PerformanceObserver. I'm going to mostly pick on LongTasks here, since it's the Observable-only spec right now (even though I love it :):

  1. As a web developer, if I'm browsing on my local computer and see a performance issue I want to investigate, if the data is only Observeable, I will be unable to look at it after-the-fact.

    Example scenario: I'm browsing my personal site and it locked up with a white screen for a second while loading or trying to interact with it. I didn't have the developer tools already open. I want to investigate, but I only have access to things that are in the PerformanceTimeline (like UserTiming, ResourceTiming which can help), and not things that are only Observable (like LongTasks which might have helped more).

    Solutions? LongTasks could support PerformanceTimeline, and keep a reasonable buffer like ResourceTiming/ServerTiming do. Or, if Observable-only, maybe there's a flag I can enable in developer tools to tell it to not clear PerformanceObserver entries at onload? Or, always monitor via TamperMonkey (below).

  2. As a web developer, if I just want to explore or play around with a new spec that is Observeable-only, it's really hard to do in Dev Tools. In order to capture data during the page load process, you have to argue with the developer tools in a race to get your Observer started in time.

    Example scenario: I'm trying to see LongTasks for site X during onload, so I hit reload in the browser. I then frantically try to get the Console to accept my PerformanceObserver.observe (below) just so I could see all LongTasks that happened during onload.

    Solution: To work around this, I'm using a third-party extension (e.g. TamperMonkey) to register my PerformanceObserver at the start of the page load.

(new PerformanceObserver(function(list) { console.log(list.getEntries()); }))
.observe({ entryTypes: ["longtask"] });
  1. For RUM, to get a complete-ish picture of the page's Waterfall via ResourceTiming and PerformanceTimeline, we can traverse into all IFRAMEs, e.g. calling performance.getEntriesByType("resource").

    We can't do this only using an Observeble-only spec, as new IFRAMEs can be added by other (third-party) scripts. There's no way for us to force an observer into those IFRAMEs in time, so we'll miss those events.

    With the PerformanceTimeline, we can leisurely crawl the page's IFRAME tree when we beacon our data, getting all entries when needed.

  2. For RUM, if we want to monitor an Observable-only interface, we need to add a <script> as early as possible in the <HEAD> to turn on the observer and start buffering, since we try to load the main RUM script async (which often arrives after onload). With PerformanceTimeline, we can leisurely capture this data when needed.

I totally get all of the reasons for the Observer, and why UA's might not want to have a global buffer for high-frequency entries. But many of the specs expect only 10s or max 100s of entries by default.

So I guess what I'm saying is, Long Live the PerformanceTimeline!

@spanicker
Copy link

Buffering the last N (~150?) long tasks should address these cases - right?
If so that seems like a reasonable proposal to me.
No need to allow explicitly clearing the buffer.

@cvazac
Copy link
Contributor

cvazac commented Jun 7, 2017

@spanicker do you mean the first or last N long tasks? If you mean first then that aligns with server timing, which I think is the right thing to do.

@nicjansma
Copy link
Author

nicjansma commented Jun 7, 2017

Yeah as long as there's buffering, that would address all of the concerns above. Buffering first (e.g. implementing PerformanceTimeline support) matches the behavior of all the other specs, but that requires clearXbuffer APIs.

@igrigorik
Copy link
Member

There is overlap here with #78:

a) Global perf buffer is not cleared at onload.

  • Each upstream spec defines whether and until when it wants events to be buffered.
  • Our default recommendation is to buffer up until end onload only. Otherwise, the timeline simply won't scale to all the use cases we want in the long-term.

b) Keeping last 150 entries of each type could work but comes with significant tradeoff.. Namely, that implicitly flips the model from "only monitor and log what the developer needs" to "always monitor all the things, in case the developer wants it". The latter has overhead and something that we explicitly discussed and wanted to avoid when designing PerfObserver -- our goal is to have minimal footprint on the runtime; observing all the things is an anti-pattern.

Example scenario: I'm trying to see LongTasks for site X during onload, so I hit reload in the browser. I then frantically try to get the Console to accept my PerformanceObserver.observe (below) just so I could see all LongTasks that happened during onload.

We need to update LT to follow the new buffer logic.. LT events queued up to onload will be stored in global buffer, which you can then query and setup your observer.

We can't do this only using an Observeble-only spec, as new IFRAMEs can be added by other (third-party) scripts. There's no way for us to force an observer into those IFRAMEs in time, so we'll miss those events.

Ditto, same as above.

For RUM, if we want to monitor an Observable-only interface, we need to add a <script> as early as possible in the to turn on the observer and start buffering, since we try to load the main RUM script async (which often arrives after onload). With PerformanceTimeline, we can leisurely capture this data when needed.

This all still works with the new buffer behavior, right?

@igrigorik
Copy link
Member

Opened: #81 - anything else we need to capture there from this thread?

@igrigorik
Copy link
Member

Let's merge threads in #81, closing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants