W3C home > Mailing lists > Public > public-web-perf@w3.org > June 2011

Re: Further concerns with PageVisibility

From: Kyle Simpson <getify@gmail.com>
Date: Wed, 15 Jun 2011 15:11:40 -0500
Message-ID: <FDE65924E8F54015A1EF6FACC468B1DE@spartacus>
To: <public-web-perf@w3.org>
Cc: "Jatinder Mann" <jmann@microsoft.com>
>> 1. confusions of the various conditions under which a window goes through 
>> visible (and partially visible) states in various OS's and devices
>
> As we have discussed on the mailing list and the conference calls, this 
> specification defines Page Visibility in a platform agnostic manner. The 
> definitions of Page Visibility must be generic enough that they will work 
> across platforms.

While the spec may be taking great pains to be platform-agnostic, my 
concerns are primarily about how I see this playing out in an 
implementation-specific way. It's the difference between theory and 
practice.

I think PageVisibility is setting confusing traps where implementations will 
have a lot more complications to deal with. What this means to me as a 
developer is that I'll have more cases where a browser ends up deciding to 
do something undesirable, then I'll have to file bugs with that browser to 
get them to change it, blah blah blah. I want to avoid such traps *wherever* 
possible.

One way to avoid such traps is for a spec to be absolutely clear and 
unambiguous. In this case, I think you'd agree that this is not only 
undesirable, but impractical.

The other way is to avoid an API that sets such traps, for instance, a 
simpler API (that still fills all the use-cases) with not only fewer states, 
but much less ambiguity of exactly which state a browser can be in.

The nature of layered windowing systems, as they exist across hundreds of 
different device+OS combinations, is asking for each particular combination 
to have to go through a lot of usability testing to find out exactly which 
side of the ambiguities they should come down on.


> >> 2. It lacks the "de-bouncing" inherently required to effectively work 
> >> with it as a "throttling" trigger for various activities (meaning we'll 
> >> have to manually author setTimeout type de-bouncing every time).
>
> "de-bouncing" may be a concern in the preview cycling scenario

That's one case, yes, but there are others. For instance, if I have two 
browser windows open, both inactive but "visible", and they're layered on 
top of each other in such a way that I could accidentally click one to 
activate it, but mean to click the other (this happens all the time for 
people like me who use many tiled windows). If I click the wrong one, and 
"immediately" correct my mistake and click the other, I'll cause the 
incorrectly clicked on page to become "visible" for a split second and then 
"invisible" again.

Another example (again, quite common for me), is having multiple instances 
of a browser window open, where my windows taskbar has a list of all of them 
available by clicking the grouped task-bar entry. I see the "menu" (of 
sorts) of each instance... but it's not always clear exactly which one is 
the one I want to open (if the titles are ambiguous or unclear), and so I 
regularly will accidentally click one, and then very quickly realize I 
clicked the wrong one, and switch (sometimes with a quick alt+tab 
keystroke). Again, this will fire a very quick succession of "visible" and 
then "invisible" states.

In both those scenarios, and several others I could construct, the rapid 
succession of "visible"->"invisible" (or "invisible"->"preview" or 
"visible"->"preview") state changes *MUST* be something that I, as a web 
developer, take into account if I'm ever going to implement such behavior on 
a page. It would be quite ignorant to just blindly listen for the "visible", 
"preview" and "invisible" state changes and not at all pay attention to how 
close in proximity they fire.

So, in almost any use-case I can construct for such an throttling API in my 
JavaScript, I would almost always have a minimum de-bounce time of say 
200-400ms, where I would not respond to an event (a state change) until I 
was reasonably sure that the state I arrived at was stable (at least for 
"now").

Can you give me counter-examples where de-bouncing (in the rapid state 
change scenarios I described) would be overkill or irrelevant, for the 
throttling performance concerns?


> "de-bouncing" protection... can be added by the web developer using the 
> Page Visibility API.

I maintain that almost all responsible uses of this API will, in practice, 
need to have some sort of debouncing intelligence built-in. Developers may 
start out with the assumption of just subscribing to the event, but I think 
as they hone the behavior of their page and go through more extensive 
testing or user-feedback, in most cases they'll wind up needing to add at 
least some fashion of de-bouncing, if nothing than to account for users like 
me.

For instance, imagine a page fires off an XHR on every state change... and 
imagine I as a user am prone to this mistaken browser activation quite 
frequently... a server admin will see the clogged log full of patterns of a 
bunch of "visible"/"invisible" pairs of requests, and he'll probably tell 
the developer to figure out how to reduce those things. How will that 
developer do that? Debouncing.


> (if the scenario even needs it)
> ... Microsoft firmly supports creating a Page Visibility API...

I think you may be listening more to browser vendors' requests for this API 
than you are considering how real-world web developers will have to interact 
with it.

I have a long career of experience as a web developer, and my strong 
instinct is that this API will be one that developers eventually realize has 
such rough edges and they'll wish it wasn't so. I think it's healthy for us 
to consider such things now, before we're so locked into the API that 
changing it is impractical.

If it's a choice between what browser vendors want/need, and what web 
developers want/need, we should make sure we're giving a lot more weight to 
the developers' concerns. I'm speaking as a developer, and I feel like 
you're not giving much credence to my concerns.


> User Idle.... Page Visibility gives a web developer a means to 
> programmatically determine if the Page is not visible and throttle down 
> page activity and resources. These are two separate and complimentary 
> APIs.

There's far more overlap between them then you are giving credit to. Namely, 
almost the entire set of use-cases for PageVisibility can be handled by 
PageIdle, whereas PageIdle (with debouncing built in) cannot be replaced by 
PageVisibility by itself, because debouncing must (often) be implemented on 
top of it.

I think if you were to have a dialogue with web developers who would 
consider "throttling" a page's activity down under certain circumstances, 
they would probably tend to initially say "well, I'd throttle it down when 
the page is not visible".

BUT, if you dig any deeper in such conversations, I think most developers 
would come to realize that when they are saying "when the page is 
invisible", what they really *mean* is "when the page is inactive/idle".

This is what I mean by saying that "PageVisibility" is a half-implementation 
of PageIdle, because I think on critical examination, most people who say 
that "visibility" is the trigger probably intend for "(in)activity" to be 
the real trigger.

Do you have any evidence to suggest that this analysis is baseless or 
irrelevant?


> The definition of "autoplay" will not change due to Page Visibility. If a 
> developer doesn't want to auto play a video, the "autoplay" attribute 
> should not be used on the video element. Instead, the developer should 
> check for visibility, and accordingly play the video.

I wasn't asking if "autoplay" will change due to Page Visibility. I was 
asking if "autoplay" will change as a result of a page being in the 
"prerendered" state, in the way that Chrome is now experimenting with. It's 
quite clear that "prerendering" as a functionality requires some sort of 
flag to indicate the state (for pages who want to opt-out, if nothing else), 
which is why PageVisibility is a necessary component.

If it is determined that the "prerendered" state (and thus the prerendering 
itself) creates problems for facilities such as "autoplay" or "autofocus", 
then I think it absolutely is something that we should be discussing as it 
relates to PageVisibility (since that affects one of its states).

How ridiculous would it be if I visit page A, and a few seconds later I hear 
some audio playing in the background, and it's because the browser 
prerendered (and started autoplay playing) audio/video on page B, which I 
haven't even visited yet. That'd be absurd. So implementations are going to 
have to address this issue.

If a browser chooses to resolve this problem by simply delaying all such 
behaviors until the first "visible" state is fired, then it ABSOLUTELY 
matters that we have to be clear and crisp in the definition of 
"prerendered" state what that actually means, and also that we call out the 
special nature of only the first "visible" state change.

If we're providing an interface for JavaScript developers to do special 
behavior (during a certain state like the "prerendered", or upon a special 
state change like "prerendered" to "visible"), then we have to tell them 
what that means, exactly and specifically. In other words, that state means 
X and Y, but doesn't mean Z.

If one browser delays autoplay playing until first "visible" state, but 
another browser doesn't, this will wreak havoc on JavaScript developers who 
rely on such things, especially since that quirk of behavior will be 
completely non-featuretestable.

If we leave what all that means up to implementations, then we'll create a 
confusing and untenable API for most developers, and create even more 
"traps" (like I said above) that I think we could and should avoid.


> Page Visibility is not being kept because of prerender - Page Visibility 
> is designed, as I have stated prior, because there is value in providing 
> the visibility information to developers.

Respectfully, I think you missed the subtlety of my wording. Kept vs. 
designed. I understand the original design as being more broad (and gave 
credit to it).

But, in our discussions (list, phone, etc), I've repeatedly asked for any 
example/use-case where PageVisibility more completely addresses a use-case 
that a PageIdle API would not. In other words, is there any reason why 
"visibility" is a more important/useful trigger for throttling than 
idleness? Or, is there anything that visibility gives us which idleness does 
not?

The *only* example given that had any credibility was the prerendering, 
which I readily admit is not addressed by PageIdle.

So, in my mind, insisting on keeping PageVisibility (which is more 
complicated and has unresolved questions to it) in addition to a possible 
future PageIdle, instead of even *considering* (you have flatly rejected 
this as a possibility) that PageIdle could be a valid and simpler 
*replacement*, is based in significant part on the fact that PageIdle 
doesn't address the prerendering functionality that vendor(s) are asking 
for.

I understand that you've asserted that the two are complimentary APIs, but I 
do not see them as such, nor have I seen any discussion which actually 
supports that in a plausible way. If you suggest they are complimentary, 
then you have to identify how the two are different in co-equally useful 
ways. Almost all the usefulness of PageVisibility is covered by PageIdle, so 
the co-equally different stuff is rather hard to find.

I renew my standing question: if PageVisibility had not already been 
"adopted", and we were still in the design phase, is there any solid reason 
(*besides prerendering*) why PageVisibility would be better than (or needs 
to exist in addition to) a PageIdle?

If there isn't a valid argument for visibility over/in-addition-to idle, 
then I submit to you that you're keeping visibility primarily because of 
prerendering, specifically.



--Kyle

 
Received on Wednesday, 15 June 2011 20:12:27 GMT

This archive was generated by hypermail 2.2.0+W3C-0.50 : Wednesday, 15 June 2011 20:12:28 GMT