Open bmaurer opened 7 years ago
The way I envision this API working is that it would provide a promise for a high resolution timestamp of the time when all the DOM mutations that have currently been done are painted on the screen.
I doubt we can provide this as high-resolution time, as it opens up all kinds of paint-timing attacks. The "imprecise" nature of rAF -> setTimeout(0), or double-rAF technique, is probably the best we can offer here. Ditto for explicit notifications of "no drawing was necessary", as that would provide an explicit signal for ~visited attacks; don't think we can offer this.
Given the above.. I'm not sure we can do much here? @toddreifsteck wdyt?
I'm sure we can find some middle ground here to avoid side channel attacks. Some compromises I could think of are:
1) Giving the timestamp of the style / layout calculation (which you could in theory trigger yourself by querying the height of the document) 2) Only including the paint time if the paint time is over X milliseconds (on the theory that a long paint would be observable via a high frequency timeout) 3) fuzzing the timestamp that is returned.
Ultimately performance is about measuring the time at which the user sees something -- right now there's not a lot of heuristics to do this. We've found that rAF + setTimeout has way more variance than we'd like (eg due to background tabs). Even something that was a better supported version of rAF + setTimeout would help
For the issue with when page is in background: this is easy enough to filter out based on pagevisibility - no?
"no drawing was necessary" does not mean that the rendering pipeline did not need to run, in fact it could have run upto one of N points. for some background see this doc
@tdresser could some of the work you're investigating with Event Timing be helpful in this discussion? Or, more broadly, anything we want to investigate or pursue here from your perspective?
I'm digging into solutions to the general set of problems here for event timing.
We can't let you know when no drawing was necessary, for the security reasons discussed above.
There's two main things an API could potentially improve over rAF+setTimeout(0):
Behavior in background. As spanicker mentions, pagevisibility should let you exclude these cases. I think exclusion is probably correct?
Knowledge of compositing time.
You can polyfill something pretty good here today by injecting an iframe with a FP listener, but it's quite ugly.
My preference would be to tackle this after we've sorted out event timing. Assuming we can sort out the security / privacy concerns there, I'd like to:
This is a followup to:
https://groups.google.com/a/chromium.org/d/msgid/progressive-web-metrics/CAHTsfZD1zJp6unenAyu%2BKoDJLAfKG41Mm2mmbT9gUKzoMvnxWQ%40mail.gmail.com
At Facebook when we measure performance, we want to know when the user sees the thing that we're measuring. For example, we don't care when newsfeed was put in the DOM, we want to know when the pixels painted on the screen. So far the best way we've discovered to do this is doing a rAF and then within that rAF a setTimeout(0). the rAF ensures we capture everything within the frame and the spec runs setTimeouts from within a rAF in the next frame.
This heuristic has a number of problems:
Tim's event timing proposal is based on the idea of measuring the "time to next paint". It'd be great to standardize this concept and create a simple API for measuring it. The way I envision this API working is that it would provide a promise for a high resolution timestamp of the time when all the DOM mutations that have currently been done are painted on the screen. If the browser does not intend to immediately render these (eg because the tab is backgrounded and it will defer drawing to a later time or because no drawing is necessary) the promise will return null.