- From: Ilya Grigorik <igrigorik@google.com>
- Date: Mon, 5 Jan 2015 16:35:05 -0800
- To: erik.arvidsson@gmail.com, public-web-perf <public-web-perf@w3.org>
- Cc: Olli Pettay <olli@pettay.fi>, Eli Perelman <eperelman@mozilla.com>, Joshua Peek <josh@joshpeek.com>, Nat Duca <nduca@google.com>
- Message-ID: <CADXXVKpdTk_Xssi1cMfTu8w+rikV4uCbvk4hDnH7WFKkPRrp8A@mail.gmail.com>
+Erik "Today, ECMAScript code wishing to observe changes to objects typically either creates objects wrapping the real data or employs dirty-checking strategies for discovering changes. The first approach requires objects being observed to buy into the strategy, making the user model more complex and eroding composability of concerns. The second approach has poor algorithmic behavior, requiring work proportional to the number of objects observed to discover if any change has taken place. Both require increased working sets." [1] The above statement is a good description of the very problem we're trying to solve for the performance timeline. Right now we have to rely on dirty checking (plus have race conditions between multiple observers), and so far we've been talking about creating an alternative ~observer API.. which is a step forward, but doesn't address the composability concern. With that in mind, it seems like Object.observe has already solved this, plus more: - synthetic change records via notifier - event filters via acceptList - higher-level change records (aggregation, etc) - observing multiple objects with a single callback - ability to aggregate large changesets and focus on performance - existing polyfills, and so on. I'm covering the highlights, for full details see: - http://www.html5rocks.com/en/tutorials/es7/observe/ - https://github.com/arv/ecmascript-object-observe - https://github.com/arv/ecmascript-object-observe/blob/master/UsageExamples.md Concretely, the API would ~look like the following: ---- def observer(events) { events.forEach(function(event) { // process event: event.entry.name, event.entry.entryType, etc... }) } // to subscribe to all perf timeline events... Object.observe(window.performance, observer, ["navigation", "resource", "mark", "measure", "renderer"]); // to unsubscribe Object.unobserve(window.performance, observer); ---- It seems like the right solution here is to extend our Performance Timeline [2] to be compatible with Object.observe, instead of trying to invent a new API... I think we would need a few special provisions* (similar to how Array.observe provides a more efficient+detailed implementation), but otherwise window.performance would just be another observable object. * special provisions: keep propagating changes if buffer is full, don't send notifications on buffer clear, and so on. *Erik*: your name is on the Object.observe spec, wondering if you can provide any thoughts or recommendations? For context, see: https://github.com/w3c/performance-timeline/issues/1 - apologies about the length of the thread, I think we've been incrementally reinventing O.o() :-) [1] https://github.com/arv/ecmascript-object-observe#problem [2] http://w3c.github.io/performance-timeline/#sec-performance-timeline On Tue, Dec 9, 2014 at 4:55 PM, Ilya Grigorik <igrigorik@google.com> wrote: > > On Mon, Dec 8, 2014 at 5:14 PM, Nat Duca <nduca@google.com> wrote: > >> Correct me if I'm wrong, ilya, but the reason I think we were looking at >> specifying when events are inserted in the timeline was because there were >> no callbacks when events were actually inserted. This made it hard for JS >> to "await" a navigation event. >> > > Yep, exactly. We don't have a notification mechanism for new perf events, > which means that applications need to poll the buffers (ugh), and run the > risk of trampling on each other (e.g. someone clears the buffer, causing > everyone else to miss events). > > In PerformanceObserver, you would make an observer for nav events, listen >> to its callback and then disconnect when they arrived. In that model, its >> up to the browser when to deliver those callbacks, which lets us defer >> their delivery as long as we think is necessary to get good performance. >> That's much better for performance. >> > > Nav events in particular are probably not the best example, but otherwise > yes that's exactly the model - e.g. listen for one of "mark", "measure", > "resource", or "render" perf events and run relevant processing. > > >> Ilya: to your point, having observers always get notifications sounds >> great. But, if so, I wonder if we can figure out how we can specify things >> like frame-timing events to never add to the buffer in the first place. >> Since they have nonzero overhead to collect, we'd be avoiding a footgun if >> they're only obtainable via observers. >> > > I've entertained the same thought.. if we have observers, do we need the > buffer at all? And I think the answer might still be yes: what if I want to > get frame-timing events for the initialization sequence of the page, prior > to my app registering an observer? E.g. get timing events for first > frame(s)? Does that mean I must register my observer as very first thing on > my page, and will that give me what I'm after? > > ig > > > >
Received on Tuesday, 6 January 2015 00:36:13 UTC