Re: [Paint Performance] - Exposing paint rects to the DOM

One way would be to use CSSOM to mutate the rule which specifies the
:visited color. If that triggers a paint then the link was visited. If it
doesn't trigger a paint then the link wasn't.

In gecko you could probably even simply change the href of the anchor from
something you know the user hasn't visited (like a made up url) to
something the user might have visited. If there's a paint the user had
visited the site.

Additionally in gecko we update the color of links when user visits URLs in
other tabs. That would let a website detect when the user visits a
particular site in a different tab.

/ Jonas
On Aug 13, 2013 12:31 PM, "Patrick Meenan" <pmeenan@webpagetest.org> wrote:

> I'll do a bunch of testing to see if I can find a way it could leak state
> but as best as I can tell you can't toggle visibility based on visited
> state (at least in Chrome) so the paint information should be the same for
> visited/not links.  The paint information is also too broad to provide a
> timing-based attack (I'll need to check and see if we post-process the
> history and change the color after initial paint but at least in my initial
> testing it looks like we have the state on the initial paint).  The paint
> events we're looking to expose are aggregated rects that cover the whole
> area that changed, not when every element gets changed so that may be part
> of it.  If there's another vector in there that I'm not thinking about I'd
> love pointers.
>
> Thanks,
>
> -Pat
>
> On 8/13/2013 2:40 PM, Jonas Sicking wrote:
>
>> Gecko used to have something similar. One problem that was hard to
>> solve was avoiding when :visited links were matched. I.e. avoiding
>> enabling history sniffing.
>>
>> / Jonas
>>
>> On Tue, Aug 13, 2013 at 10:14 AM, Patrick Meenan
>> <pmeenan@webpagetest.org> wrote:
>>
>>> I'm working on exposing Chrome's paint events to the DOM so that sites
>>> can
>>> report visual metrics back as part of their RUM.  I know there is a lot
>>> of
>>> controversy around paint events but it would be great if we could at
>>> least
>>> define how they could be exposed should a browser vendor decide to expose
>>> them.
>>>
>>> I can write up a full proposal in the formal template but I wanted to
>>> throw
>>> out a straw-man that basically mimics the behavior of the resource timing
>>> interface.
>>>
>>> - The paint events will consist of a rectangle (left, top, width, height)
>>> and a DOMHighResTimeStamp relative to the start of navigation
>>>
>>> - The array of events would be fetched through
>>> window.performance.**getPaintEvents()
>>>
>>> - The number of events to be tracked can be set by
>>> window.performance.**setPaintEventsBufferSize(#of events) and defaults
>>> to
>>> something reasonable given the events are quite small (actual numbers TBD
>>> but 1500 as an initial default would not be unreasonable)
>>>
>>> - The accumulated paint events can be cleared by calling
>>> window.performance.**clearPaintEvents()
>>>
>>> - An event (onpainteventsbufferfull) will fire when the buffer is full
>>> (TBD,
>>> should this be a rolling window and always drop from the head instead of
>>> failing to insert?)
>>>
>>> - The paint events will be bound to the document that they belong to
>>> (paint
>>> events for frames are tied to that specific frame).  Otherwise there
>>> will be
>>> all sorts of opportunity for privacy leakage (embedding an iFrame to a
>>> bank
>>> page and watching where it paints for example).
>>>
>>> A couple of other nice-to-have's:
>>> - Standardize a firstPaint attribute on the Navigation Timing interface
>>> - Standardize a bodyStarted attribute on the Navigation Timing interface
>>> (technically easy to capture in js anyway but I'm planning on filtering
>>> out
>>> all of the bogus paint events before the browser hits the body and
>>> thought
>>> it might be useful for RUM to get for free)
>>> - Provide an interface for helper calculations (I'm planning for a simple
>>> way to get SpeedIndex without everyone having to implement the algorithm
>>> against the raw paint rects for example)
>>>
>>> I know that browsers can't necessarily expose the exact time when pixels
>>> hit
>>> the screen because they pay offload a lot of that to hardware but the
>>> plan
>>> is to get as close to that as possible.  In the case of Chrome there
>>> could
>>> be a difference of 10's to 100's of ms between when blink passes a rect
>>> off
>>> to be rendered and when it hits the screen but the information available
>>> from blink is still worth exposing (and matches what you get in the dev
>>> tools when you show paint rects and in the timeline).
>>>
>>> Thanks,
>>>
>>> -Pat
>>>
>>
>

Received on Wednesday, 14 August 2013 09:22:30 UTC