Web Performance Working Group Face-to-face

26 Oct 2015

See also: agenda, IRC log

Attendees

Present
Yoav, plh, Ilya, Todd, Ryosuke, Alex (afternoon), Xiaoqian (afternoon), Bartek, Mark (morning)
Regrets
Chair
Ilya & Todd
Scribe
Yoav

10,000 feet view of Web Performance deliverables

igrigorik: 10,000 feet view of WebPerfWG

Web perf overview

High resolution time is the foundation of the WebPerf APIs

we recently made sure that it works well with both window and worker

igrigorik: translateTime recently added to HRT

igrigorik: we also have a problem with people finding the old version of HRT rather than the new one
... The next big chunk is performance timeline
... PerformanceObserver was added. It enables to subscribe to notifications about various metrics
... ResourceTiming: pretty simple and not many recent updates
... Navigation Timing is being refactored to be based on resource timing
... There are fetches that are multiple fetches under the hood, and we need to figure out a way to un-mush that

todd: We need to figure out a way to so that securely

igrigorik: user timing, some cleanups but no major changes
... Server-timing - no implimentations today

todd: the main blocker there is trailer headers

igrigorik: without trailers a lot of the use cases are lost

mnot: there is pushback about supporting trailers in browsers

<plh> fun fact: https://w3c.github.io/server-timing/#the-performanceservertiming-interface actually defines an interface called "ServerTiming"

igrigorik: we could just expose certain headers (e.g. server timing) there, and not generic support for exerything

todd: ServerTiming can be done, but would be more interesting with trailers

igrigorik: server timing spec has been stable for a while, but we could convert it to performance observer

todd: Agreed, but we'd need to be able to define it for the navigation request

igrigorik: as long as you register the perfObserver early, you could do that

todd: would be great if there was a declarative way to do that

igrigorik: FrameTiming: recently changed so that frameTiming only measured frames that exceeded their budget

The whole spec addressed a big gap that we have regarding measuring run time

rniwa: when we looked at frame timing, it didn't make much sense.

todd: the recent spec matches RAF much more closely, and the compositor references are now gone

rniwa: intersection observer could have also be used to measure something like that

igrigorik: Beacon API currently based on fetch. couple of open issues

we need to send different payloads, which may trigger CORS preflights and questions RE credentials

preload - we'd done a few loop around the track on how to determine priority. It's been addressed with hooks into fetch. Exposed as the `as` attribute

igrigorik: originally, preload was part of resource hints, but now it's split into its own spec, since is has mandatory semantics

Resource hints - preconnect is shipped, and used by some Google properties

dns-prefetch, prefetch, prerender mostly retro-speccing the implemented bits

igrigorik: prefetch and prerender are highly heuristic, and hard to predict as a developer when they'd kick off
... in the spec we talk about downgrading resource hints, but it doesn't look like any of the implementations do that

todd: What we've seen with internal properties, it takes them a lot of time to experiement and figure these hints out

rniwa: maybe developer tools could help us there

bartek: Would it be possible for regular developers which parts of the draft are implemented and shipped?

igrigorik: plh has a implementation document

NEL - no current implementation in Chrome, Firefox are looking into it

igrigorik: Working with Mike West on a reporting API, so that we can report NEL, CSP, HSTS and everything else

bartek: Would be interesting to have that info in DNS headers

so that the browser can know what the reporting URL is

igrigorik: so once the reporting API would be in place, we'd reactor NEL based on that

requestIdleCallback - used to run some code at idle time so that it won't get in the way

todd: Page Visibility enables developers to know if the current tab is visible

there was some dicussion about out-of-view iframes, but we didn't move forward with that

todd: one last item is CPU and memory monitoring, but it can be tricky for security reasons

igrigorik: we've been talking in Chrome about killing the onunload event

on mobile you should listen to page visibility rather than onunload

igrigorik: and since it's broken in many browsers, we could just remove it, since devs can't rely on it

todd: this also means that the page visibility API may rise in importance

plh: we can add a section to the spec to talk about that

rniwa: when the users switch a task, focus and blur is changed, and currently not specified anywhere

igrigorik: might be specified in the HTML spec, but not implemented in a consistent way

Yoav: how about visibility metrics? need paint observers?

rniwa: interested as well. we don't know what's important for each page

Other items discussed: Declerative way to improve first paint and prevent CSS blocking

igrigorik: profiler API would be interesting

todd: it'd be interesting to expose how well the Web page performs on the machine it's working on

igrigorik: There's a proposal for interventions in Chrome, so that the browser can break the API contracts in some cases, in order to improve the user experience

part of that is signaling to the origin that the intervention took place

which loops back to the reporting API

we could observe the lifecycle of the page and at the end send back a report

rniwa: it's usually more interesting to have aggregate data

igrigorik: that depends. In some cases that's true, and in some cases it's interesting to have granular data

yoav: in terms of out-of-band reporting, it might be interesting to expose that to users eventually

HR timing 2

plh: What do we do with the spec? there are no implementations of translateTime

igrigorik: it can be polyfilled

plh: who is exposing performance.now in workers?

igrigorik: Chrome is

todd: workerStart is tied to service worker, where translateTime is realted to workers in general

plh: Should we not ship translateTime in the spec?

todd: we could publish without translateTime, and then publish translateTime in the next release

plh: so we just need to make sure we have a test that tests the worker support
... so the goal is to push HR time 2 to REC, but without translateTime.

*Discussion about https://github.com/w3c/hr-time/pull/14

<plh> The term <dfn>current document</dfn> refers to the document associated with the Window object's newest Document object

<plh> The term <dfn>current document</dfn> refers to the Window object's newest Document object

Everyone: Let's just add a note referring to the bug on HTML

<plh> The term <dfn>current document</dfn> refers to the Document object returned by Window.odocument

<plh> The term <dfn>current document</dfn> refers to the Document object returned by Window.document

todd: second issue https://github.com/w3c/hr-time/issues/15

this will be resolved once we'd publish the new spec

plh: Need to do the "great renaming" where the old spec changes urls
... Also, we can push current spec to CR with translateTime "at risk" so that we can later add it in once implementations catch up

Performance Timeline

plh: the biggest issue is from resource timing and navigation timing

in both we have "clear" which when based on PerfTimeline does nothing. I wrote a pseudo polyfill on the plane.

If we only register perfObserver at the head of HTML, you're racing and might miss some resources

todd: For frame timing, it's defined as not injecting to the timeline, but only emits performanceObserver

igrigorik: We agree that all API should be based on PerformanceObserver. I think that some APIs don't need a buffer in addition to that

but in some cases, we need a buffer - especially for resource timing and keeping track of resources that may finish loading before perfObserver registration is done

todd: perhaps the way to get perfObserver on everything is to have an initial buffer, and then the first event grabs everything from that buffer and onto PerfObserver

plh: I don't think we can change getEntries() because they are heavily used

It would be interesting to polyfill them using perfObserver

todd: that makes sense.

*discussion about eliminating buffers entirely, getting an initial buffer in place, etc

plh: if we could remove the setResourceTiming size, it'd make it easier to just define a start buffer

igrigorik: we could also limit buffering up until the onload event

so that users in their registration would read the buffer and then start observing from that point on

yoav: there's some race condition here if users read first and register later

plh: yeah, but if they register first, we're all good

rniwa: it'd much nicer to have a flag so that when you register the observer, you get all the past entries as well

todd: so that browsers that haven't implemented getEntries() (Safari/WebKit) never have to buffer after onload

plh: do we even need the flag?

rniwa: it makes sense for the default to be to get all the past entries
... it might be nice to be able to filter what you want recording

todd: currently you're getting an array and you can filter it

rniwa: in MutationObservers you can listen to a single node. It would be nice to filter based on a single resource

igrigorik: Alex Russel also wants to be able to query the img resource related to a single DOM element

todd: We can tell with initiator type, but not everything

yoav: how would that data be useful? If you have multiple elements referring a resource, it's still a single entry for a single fetch

rniwa: anyway, it would be nice to be able to filter based on an element

todd: we can filter by name

plh: but we don't allow filtering by name on perfObserver

igrigorik: It's a list, and devs can just ".filter" on it

plh: getEntriesByType("resource") was added so that you don't need to create the JS types for anything that won't go into the JS list

todd: That's not necessarily a concern today

igrigorik: Nat Duca supported adding the GetEntriesBy* when we were talking about thousands of entries

for a smaller number, it might not make sense

todd: we see 3 getEntries() for every 2 getEntriesByType() for 0 getEntriesByName()

plh: We can't remove these methods, but we can move them to a historical section

todd: We should wait with deprecation until we have a replacement specced and shipped in enough browsers

plh: so let's promote perfObserver in a way that could one day used to replace getEntries*

igrigorik: so let's imagine we only had perfObserver. We could tell developers to add a shim that emulates getEntries*

* Discussion on Performance Observer and {how/if} we can obsolete the getEntries* methods

* Overall discussion tends to get rid of getEntries* from perfObserver

todd: FrameTiming was defined to not buffer, but maybe in the initial buffer model we want to buffer it

igrigorik: so until onload we buffer anything. We can also have some opt-in to only buffer certain types.

rniwa: buffering is not expensive, but measuring can be expensive so an opt-in would be useful

igrigorik: FWIW, today RT and NT already measure and it works fine without huge overhead

todd: Let's separate frame timing from perfObserver for the moment and discuss that separately

igrigorik: so to keep things simple, the buffer buffers everything up until onload
... to complicate things further, fetch registry might also add resource timing that is unbound

todd: that's an issue for the fetch spec to deal with

for our purposes, the "up to onload" buffer can probably be bound to 500

* Discussion about some opt-in for PerfObserver

discussion on perfObserver's buffer queueing logic

Conclusions

whiteboard screenshot
Brainstorming on how to eliminate performance.getEntries in the future

Memory API

Memory info API thoughts from Ilya

igrigorik: different implementations can report different things, developers might micro-optimize to implementation details

under-reporting browsers would look better

* Going over use-cases from the doc

two distinct use cases:

regression detection - seeing if your app memory usage increases over time

adaptation - serving a different, lighter version of your site to devices that cannot deal with the full version

todd: How would we register to getting memory reports?

plh: could be a performance entry

igrigorik: proposal is just to get an event with a performance entry with heap size and an "underPressure" boolean
... should we add other metrics? canvas size, media buffers (if we're willing to expose it)

an underPressure event would be a signal to the app that some of their users are under memory pressure in the wild

plh: the goal is to allow the application to send a beacon up

todd: and to turn things off

another goal is to be able to send up memory increases so that apps can keep an eye on memory increases

igrigorik: Another case is getting crash reports

yoav: we also need a way to detect low-end devices relatively up-front so that Web sites can load light versions of their sites for devices that can't handle more than that

plh: there would be privacy issues with exact numbers

rniwa: we could clip the numbers to the hundreds of MBs to avoid privacy concerns

whiteboard screenshot

Intersection Observer

slightlyoff: the proposal comes from traces of 3rd party content, what making Web sites slow, battery use & jank

A lot comes from third party that try to see where things are on screen

use cases:

dealy loading of content, with scroll events

analytics and ads networks

(forcing sync layout every 100ms or so)

the bad version of that creates plugins that measures things inside the viewport

IntersectionObserver lets you know how if an element that you care about hits the viewport

that answers this use case, plus enables lazy loading

It can report the top level viewport, or to report when the observed element overlaps another element

The information is async delivered and you might miss a thread or two

because multi-threading is hard

so you set an observer on an element and get notified when that element enters the viewport

with that you can meet the ad network guidelines, so ads can implement their thing using that

plh: Would that API be able to tell you if an element is visible?

slightlyoff: Only to an approximation

plh: iframes?

slightlyoff: There's a good chance that this would give you that

it can't cover if an element was hidden by a different element

slightlyoff: time is relative to the generator which may be the compositor

there can be some skew

igrigorik: about privacy and timing attack

rniwa: if it's async, there's no risk for timing attack

slightlyoff: about approximation of meaningful paint, the first intersection observer may more or less correlate with the meaningful first paint

there can be delay between layout and paint in some browsers. Also images that are painted to a viewport element won't be visible to that API

rniwa: we could also have elements that are in the viewport but never painted due to fast scrolling
... The real metric people want is when things got painted

slightlyoff: That's a metric that we can add. File an issue on the repo

rniwa: It would be great to correlate that info with frame timing in order to figure out which elements trigger jank

slightlyoff: the times are not correlated

igrigorik: the important thing is that you should be able to translate between that time and the current document time.

todd: We've had some push back for Page Visibility 2 on iframe visibility, but now with IntersectionObserver, maybe there's a chance to get that

rniwa: So the idea is the attach intersection observers to iframes if the user attached to the iframe's page visibility?

maybe, even if the async nature is making this harder

let's wait for intersection observer to be a thing before making decisions on that

TAG Review of nav-timing

Navigation Timing 2 Feedback

slightlyoff: some things are weirdly split between resource timing and navigation timing

It seems odd that there's no way to get from an element to the relevant timing. It's hard to tie the DOM and the timing back together

if there's evidence that this is something people do, it'd be good to add that back to the platform

rniwa: it would be nice to get a timing back from an element

todd: the theory is that most analytics poll the timeline regularly, so that instead of timers, PerfObservers would enable to receive events as they arrive

slightlyoff: they poll frequently in order to avoid data loss

igrigorik: it's both. You need to observe when things have changed. Then, if you delay it too long, you may lose it
... one more issue is about resources that send more than one request: preflights, redirects

we can probably unbundle that

slightlyoff: so will the APIs continue to evolve or are they done

igrigorik: they'd continue to evolve in small ways, but most of the data is there

rniwa: could we agregate the data?

igrigorik: there are several agregation implementation out there, but they're all different so there's no single way we'd want to stardize

todd: getEntriesByType(navigation) is not implemented in Firefox and Chrome

slightlyoff: Regarding attribution, it would be significantly easier to be able to get the element(s) back from the timing entries

the list of elements could be populated at query time

todd: It's interesting to look into the use cases and see if we can limit the attribution to resources that would satisfy the use-cases

slightlyoff: it may also be interesting to attribute download initiation to other resources/timing/elements

<igrigorik> http://www.webpagetest.org/breakdownTimeline.php?test=151026_HS_DQ1&run=2&cached=0

* Discussion about an API that would expose what the main thread have been doing for RUM

it's possible that just decorating frame timing with that data would be enough to get that data in the hands of users

rniwa: also, it's possible that GC time and layout times can be cheaply measured and exposed

exposing layout time can expose timing events if you wouldn't limit precision

todd: system profiling api is interesting, but we don't have conclusive data that it's needed

igrigorik: Let's add some of this to frame timing, and then see

Summary of Action Items

[End of minutes]
Minutes formatted by David Booth's scribe.perl version 1.140 (CVS log)
$Date: 2015/10/31 06:58:03 $