per stream (initial) flow window size

SETTINGS allows us to set a default starting window for all streams +
update this default later. However, I think there are compelling cases
where it would be beneficial to allow different streams to start with a
different initial window size (similar to optional priority in headers
frame). Given that this would effectively be a new feature... let me try to
motivate why the extra complexity is worth it based on some of the recent
work I've been involved with:

We want to make browser pre{fetch,rendering} smarter [1,2]. Meaning, we
want to be able to discover critical page resources as early as possible
and kick off fetches for those assets also. However, since some of these
assets are large (and there can be many of them), we need to control how
much data we fetch (e.g. if we are too aggressive we may slow down the host
page, and/or incur high overhead for the user).

A concrete example of this is the work we've been experimenting with in
PageSpeed [3], where we are aggressively inlining CSS/JS and even doing
"page splits": the rewriter effectively creates two pages, the first is the
"prefetch friendly" version which fits in < 15KB (one RTT), and second is
the diff that fills in the rest once the navigation is triggered via an XHR
-- if that sounds crazy, then that's not too far from the truth. That said,
we have a working prototype, and it's showing impressive results.. For
example, we can take a mobile wikipedia page, which currently takes 9s
(!!!) to first render (on a 3G profile), down to 1.6s [3] by using the
combination of prefetch + page split strategies.

What does flow control have to do this with all this? When issuing a
prefetch, we would like to be able to open a request with a lower initial
window (e.g. 15KB), and fetch just the head of the document - in most
cases, this will allow us to discover the critical resources, initiate
requests for them, etc. Then, if the navigation is triggered, we would just
increment the window and "resume" the stream to get the rest of the page...
This eliminates the need for server rewriting / page splitting, which has a
lot of gnarly edge conditions. Handling this at the transport layer would
make it much, much simpler and more powerful.

(Yes, we could lower the initial window for all streams, but that's counter
productive in majority of cases... we'd just end up sending a lot more
WINDOW_UPDATE frames for non-prefetch request.)

Further, the ability to set a custom window size also allows us to adjust
this logic based on type of asset, prior knowledge of the site, or other
signals. For example, the other use case is progressive rendering of images
- i.e. using flow control to fetch image layers and having control over
where and when to stop. Concretely, we could fetch first X KB, which may
provide a reasonable low-res preview of the asset, and then continue
fetching subsequent layers until some condition is met (end of file, or max
resolution of device is reached -- if you're a 2x device, don't fetch the
3x layers). I'm intentionally skipping over the image container discussions
here, since that's a separate conversation.. But I'll note that many sites
are already trying to provide this sort of experience, except through
rather poor implementation: inline low-res asset, render that, then
initiate a separate XHR to fetch image and replace with high-res version.
Needless to say, we can do much better, and there is strong interest in
providing this sort of functionality natively...

--

In short, there are interesting cases where the initiator of the stream may
want to control the initial window size: to decrease it, and perhaps even
to increase it in some cases. There are multiple ways to achieve this, but
one plausible strategy would be to allow an optional
SETTINGS_INITIAL_WINDOW_SIZE
payload in the headers frame, not unlike the optional priority field --
minimal overhead, no races between initiating the request and
WINDOW_UPDATE, etc.

Thoughts?

Ilya

[1]
https://docs.google.com/document/d/1wck0tFTiibKzZDuBeyK0lrKTKsZ5pqfvcR__1r2m834/edit
[2] http://lists.w3.org/Archives/Public/public-web-perf/2013Aug/0010.html
[3] https://developers.google.com/speed/pagespeed/optimization
[4]
http://www.webpagetest.org/result/130715_PZ_08063384bd76cd2206a1b39e8678e438/3/details/

Received on Tuesday, 8 October 2013 23:15:51 UTC