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

Allow creation of PerformanceObserver with flag to "emit timeline"? #41

Closed
toddreifsteck opened this issue Jul 20, 2015 · 8 comments
Closed

Comments

@toddreifsteck
Copy link
Member

If a site wants to use PerformanceObserver in place of the existing performance.getEntries() API, they will could encounter scenarios where it is impossible to get a PerformanceObserver created before some PerformanceEntries are emitted.

Would it be helpful to add a flag to the creation of PerformanceObserver that indicates the first event should include the existing performance timeline that match the specified filter?

This mechanism should allow PerformanceObserver to 100% replace performance.getEntries().

@natduca
Copy link

natduca commented Jul 20, 2015

This seems neat.

One thing that feels undefined in this space, but important somehow, is how to allow some performance APIs to be defined s.t. they can insert events only when there is an observer. Frame timing, for instance: we want it to be off by default, but on when someone observes it.

If you have a flag that says "absorb the items in the performance timeline," then it could make it very difficult for us to have frame timing off ever, because someone might sometime create a retro-active observer request.

Food for thought. I agree that the use case is neat. I don't think the issue I'm talking about is really to do with the proposal at hand, more that this proposal brings out an underling vagueness in the overall performance timeline spec overall.

@igrigorik
Copy link
Member

If a site wants to use PerformanceObserver in place of the existing performance.getEntries() API, they will could encounter scenarios where it is impossible to get a PerformanceObserver created before some PerformanceEntries are emitted.

What's an example? FWIW, we've said that PO entries are to be emitted only when they're 'finalized', which means that resource/navigation entries would be emitted once those fetches have finished -- tangent: we also discussed a potential route where we expose "partial" entries as standalone records.

Assuming my page ships a script block that registers PO observer at the very top, what would I miss?

@eliperelman
Copy link

Server timing marks?

@toddreifsteck
Copy link
Member Author

It could be possible to miss a resource timing from a prefetch header.

Also.. imagine the following potential race (this may not be accurate with the currently specified process model):

  1. performance.createObserver(callback)
  2. // Background prefetch 'foo' completes placing entry into timeline
  3. performance.getEntries() gets 'foo'
  4. callback receives 'foo' and the code has to deal with deduping

It seems simpler to tie allow the following which removes any risk and removes the requirements for script block at the very top:
performance.createObserver(initializeFromTimeline:true)

@igrigorik
Copy link
Member

@toddreifsteck it sounds like you're suggesting that performance.createObserver(initializeFromTimeline:true) would emit all the entries in current buffers and clear those buffers? FWIW, I don't think we can do that as that re-introduces a host of race conditions - e.g. whoever declares the first observer gets all the events, but other observers don't; non PO-aware code breaks because someone clears entries from under their feet, etc.

Also, as @natduca noted, I don't think we can or should make blanket promises about "previous events" because we may not log them until they are requested - e.g. if no-one asks for frame timing events then we shouldn't incur any overhead until such an observer is registered.

Last but not least, assuming we (a) don't clear the buffers, and (b) don't make any blanket promises about observing "previous events", I think the behavior you're looking for is trivial to implement as is:

<html>
<script>
function processEvents() { ... your logic ... };

// process buffered events, if any are present...
processEvents(performance.getEntriesByName('resource'));
processEvents(....);

// subscribe to new events 
var observer = window.performance.createPerformanceObserver(function(list) {
  processEvents(list.getEntries());
}
observer.observe({typeFilter: ['resource', '...']});
</script>
....
</html>

@nicjansma
Copy link

With a very minor race condition between the second processEvents(...) and var observer.

@igrigorik
Copy link
Member

@nicjansma true, but addressable if its a problem in practice: initialize observer first, then fetch current buffer and dedupe if/as necessary.

@toddreifsteck
Copy link
Member Author

Per 8/12 call, it may be useful to enhance PerformanceObserver in the future to allow something like this but.. the race itself is best solved by ensuring that insertion of entries into the Performance Timeline is part of the EventLoop.
w3c/resource-timing#31
w3c/navigation-timing#1

Closing this suggestion for now.

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

5 participants