<video> readyState/networkState coupling and event order

TL;DR: Should readyState/networkState expose randomness or be coupled to  
hide it?

The way the spec defines readyState and networkState, the two seem mostly  
independent. Not all combinations of readyState and networkState are  
possible, but the only limitation that is clearly enforced by the spec is  
that networkState must reach NETWORK_LOADING before readyState can  
increase beyond HAVE_NOTHING. After that, the coupling of states and order  
of state transitions is not really clear.

The issue of state coupling and event order is not at all new. There was  
originally just a single state, but it was split into readyState and  
networkState in 2008. [1] At that time, I questioned why the two were  
coupled (transitioning to networkState=NETWORK_LOADED required  
readyState>=HAVE_METADATA) and was satisfied with this reply: [2]

On Sun, 2008-11-16 at 08:03 +0000, Ian Hickson wrote:

> My concern is that people will end up with subtle bugs if the order 
> between those two are left up to the UA, and we'll end up having to  
> defineit anyway. How important is it to you that they be unrelated? (And  
> is itreally that they are unrelated, or that the NETWORK_LOADED thing  
> willalways fire before anything else if it's from cache?)

With <video preload>, it's becoming evident that if the spec is just  
implemented as it is today, there order of state transitions and related  
events is not reliable. In the following cases, the spec doesn't clearly  
say what should happen if the resource is very fast to load (fast network,  
already in cache,  data: URL, etc):

1. <video preload="none" oncanplay="this.play()">

What if HAVE_FUTURE_DATA can be reached without touching the network? I'd  
like readyState to be pinned at HAVE_NOTHING.

2. <video preload="metadata" oncanplaythrough="this.play()">

What if HAVE_ENOUGH_DATA can be reached after enough data to get to  
HAVE_CURRENT_DATA is available, e.g. because the resource is really small?  
I'd like readyState to be pinned at HAVE_CURRENT_DATA.

3. <video preload="metadata">

What's the event order? All of these are allowed by the spec:

slow network: loadstart, progress, loadedmetadata, loadeddata, suspend
unlucky timing: loadstart, progress, loadedmetadata, suspend, loadeddata
fast network: loadstart, progress, suspend, loadedmetadata, loadeddata

Maybe we could pin networkState at NETWORK_LOADING until readyState has  
reached HAVE_CURRENT_DATA to guarantee the behavior of the slow network.  
I'm not sure.

Examples 1 and 2 are basically the same as discussed in the "<video>  
readyState oddities" thread. [3] Example 3 is from a bug I filed. [4]

Since letting readyState and networkState be independent states exposes  
web developers to randomness based on the network conditions, I'm leaning  
towards coupling them into what is effectively a single state that also  
depends on preload, loading of <track> resources, etc. This guarantees a  
certain order of state transitions and events at the expense of not  
telling the truth in some situations.

How do other implementors view this problem? Would anyone be opposed to  
changing the spec to explicitly require all the dependencies between  
different states that is needed to make things predictable? For maximum  
compatibility I would actually prefer the spec to define that single state  
machine (visually or as pseudo-code), but I'll leave that to the editor  
for now.

[1] http://lists.w3.org/Archives/Public/public-html/2008Oct/0037.html
[2] http://lists.w3.org/Archives/Public/public-html/2008Nov/0151.html
[3] http://lists.w3.org/Archives/Public/public-html/2011Feb/0301.html
[4] http://www.w3.org/Bugs/Public/show_bug.cgi?id=12175

Philip Jägenstedt
Core Developer
Opera Software

Received on Friday, 25 February 2011 16:36:56 UTC