- From: Peter Lepeska <bizzbyster@gmail.com>
- Date: Sun, 3 Nov 2013 15:21:48 -0800
- To: William Chan (陈智昌) <willchan@chromium.org>
- Cc: HTTP Working Group <ietf-http-wg@w3.org>, Martin Thomson <martin.thomson@gmail.com>
- Message-ID: <CANmPAYFSOggiM8dKbWVGe3PPjMCuK1jDx0jERMsbZxn8wvkK_Q@mail.gmail.com>
Yes I was assuming that. Let me think on the two tab example you give a little more. Thanks, Peter On Sun, Nov 3, 2013 at 1:30 PM, William Chan (陈智昌) <willchan@chromium.org>wrote: > I think you're assuming that all streams in a connection belong to a > single webpage load. Let me know if not, and I can explain further. > On Nov 3, 2013 9:04 AM, "Peter Lepeska" <bizzbyster@gmail.com> wrote: > >> Right. But my point is that an extremely simple scheme, where the browser >> just indicates that an object is blocking or not, gets you to the same >> place as the dependency scheme. >> >> Peter >> >> >> On Sun, Nov 3, 2013 at 8:54 AM, Martin Thomson <martin.thomson@gmail.com>wrote: >> >>> The intent would be to use ordering (i.e. dependencies) for this >>> scenario, not "priorities" (aka weights). >>> >>> >>> On 3 November 2013 07:37, <bizzbyster@gmail.com> wrote: >>> >>>> Going through your example, would the prioritization at any instant be >>>> any different if you simply assigned two priorities -- high for resources >>>> that are blocking (the .js and the .css in your example) and low for >>>> resources that are non-blocking (the .jpgs)? >>>> >>>> Sorry if I'm missing something but it doesn't seem like it to me. >>>> >>>> Peter >>>> >>>> On Oct 28, 2013, at 3:45 PM, William Chan (陈智昌) <willchan@chromium.org> >>>> wrote: >>>> >>>> On Mon, Oct 28, 2013 at 3:34 PM, Martin Thomson < >>>> martin.thomson@gmail.com> wrote: >>>> >>>>> On 28 October 2013 14:32, William Chan (陈智昌) <willchan@chromium.org> >>>>> wrote: >>>>> > I think that the second point is far more controversial and requires >>>>> more >>>>> > discussion. >>>>> >>>>> It may be the case that you find the first issue compelling enough >>>>> that a change of some form is justified regardless of what you think >>>>> on the second :) >>>>> >>>>> Of course, I think that there are some significant problems with the >>>>> proposal, most of which I think that you will find are easy to fix. >>>>> >>>>> The first is largely procedural. I've have people complain about the >>>>> use of references to documents like the above for archival and IPR >>>>> reasons. Maybe copying and pasting the entirety of that document to >>>>> an email will address those concerns. Maybe it will also help you >>>>> understand that it is a little wordy and that perhaps the essence of >>>>> your proposal could be made more succinctly :) >>>>> >>>> >>>> I have to confess that I heard complaints but never understood the >>>> reasoning behind them. If it's archival/IPR, I'm perfectly happy to >>>> copy/paste the document into email. These concerns aren't obvious to me as >>>> I'm a relative newb to IETF stuff. >>>> >>>> As far as the proposal's wordiness, I mostly view it as a straw man to >>>> ignite discussion. I'm completely expecting that it will be ripped apart :) >>>> I'm hoping to rely heavily on editors to make it much more succinct once we >>>> reach some rough consensus. Or perhaps this was a subtle play on your part >>>> to get me to do better editorial work before sending it to the group :) >>>> >>>> I'll give others a chance to discuss other points first. I don't want >>>> to yell more loudly than others anymore than I already do. >>>> >>>> >>>>> >>>>> The second is that the idea of prioritization between separate trees >>>>> isn't really described as being prioritization. I think that what you >>>>> want to do is a proportional allocation of resources between those >>>>> trees, so a term like "weight" is probably more accurate. You even >>>>> use that word later. (Oh crap, I just realized that this is a classic >>>>> case of "the names aren't important, the standards committee always >>>>> changes them anyway" scenario, sorry.) >>>>> >>>>> Probably more substantially, you need to be a little more concrete >>>>> when it comes to requirements for managing placeholders and garbage >>>>> collection. >>>>> >>>>> The settings seem like over-engineering to me. I'm sure that a server >>>>> implementation can arrive at a reasonable set of behaviours that >>>>> doesn't degrade too badly for their common workloads without settings >>>>> being exchanged. When it comes to resource exhaustion, I think that >>>>> it's probably more appropriate to deal with those in the DoS >>>>> considerations than with settings. >>>>> >>>>> On the over-engineering theme, the idea that you can reprioritize >>>>> multiple streams with a single PRIORITY frame concerns me. That's >>>>> going to mess with intermediaries of all sorts. The cost of a >>>>> PRIORITY frame for each stream is 4 bytes per stream, but then you >>>>> weren't going to bother with that anyway. >>>>> >>>>> Please consider placing default values on priority. Since you are >>>>> only going to be able to provide either a dependency or a weight, the >>>>> complementary item is going to inherit a default. >>>>> >>>> >>>> I'm copy/pasting the doc here: >>>> Proposal for Stream Dependencies in SPDY >>>> Draft 1 >>>> Last Updated: 26 October 2012 >>>> >>>> This document proposes changes to the SPDY protocol to support stream >>>> dependencies. During a pageload, the server uses dependencies to >>>> improve performance by allocating bandwidth capacity to the most important >>>> resource transfers first. >>>> >>>> The remainder of this document describes the motivation<https://docs.google.com/a/google.com/document/d/1pNj2op5Y4r1AdnsG8bapS79b11iWDCStjCNHo3AWD0g/edit#bookmark=id.dwzsju9gmwit>for dependencies, protocol >>>> changes<https://docs.google.com/a/google.com/document/d/1pNj2op5Y4r1AdnsG8bapS79b11iWDCStjCNHo3AWD0g/edit#bookmark=kix.hiogy1u6j43a>to support them, and >>>> examples<https://docs.google.com/a/google.com/document/d/1pNj2op5Y4r1AdnsG8bapS79b11iWDCStjCNHo3AWD0g/edit#bookmark=id.9awxmm9y20yn>of how those mechanisms can be used by the browser. We conclude with a >>>> discussion of the client and server policies<https://docs.google.com/a/google.com/document/d/1pNj2op5Y4r1AdnsG8bapS79b11iWDCStjCNHo3AWD0g/edit#bookmark=id.6ii1fem7qsws>afforded by expressing dependency information in SPDY. >>>> >>>> (Note that flow control is the subject of a separate document and is >>>> out of scope here.) >>>> Motivation >>>> In SPDY today, each stream has a priority (0–7) chosen by the client >>>> upon stream creation. Push streams are >>>> an exception. The server policy today is to assume push streams are all >>>> low priority. Push or pull, the priority of a stream cannot be changed once >>>> created. >>>> >>>> Priorities provide hints to the server about which streams are most >>>> important to the client, but they are poorly suited to several common >>>> use-cases. >>>> >>>> >>>> - Specifying an ordering of resource transfers >>>> Sharing bandwidth between resource transfers may degrade >>>> performance as measured by page-load time, e.g., when transferring two >>>> Javascript resources that cannot be executed until transfer is complete, or >>>> two video chunks that will be played back-to-back. In these circumstances, >>>> the browser may wish to specify an ordering --- HTML before script1.js >>>> before script2.js before image.png, for example, or video_chunk1 before >>>> video_chunk2 and so on. (Moreover, changing the priority of the HTML >>>> transfer itself may benefit performance; e.g., a large blocking script will >>>> be interpreted and executed more quickly if it does not compete for >>>> bandwidth capacity with a large HTML transfer.) >>>> >>>> With a small number of fixed priorities, the browser is simply >>>> unable to express an ordering over many resource transfers, and with a >>>> large number of priorities, reordering is costly. >>>> - Reacting to document parsing >>>> Because the browser's document parser blocks while waiting for >>>> script and style resource transfers to complete, many resource requests >>>> will be speculative. (For more background, see Tony Gentilcore's >>>> excellent summary<http://gent.ilcore.com/2011/01/webkit-preloadscanner.html>of Chrome's implementation of speculative parsing, the preload scanner.) >>>> These requests may need to be preempted as the document parser learns of >>>> higher priority resources. For example, if a script a.js uses >>>> document.write to embed another script, b.js, the transfer of b.jsshould preempt other in-flight resource transfers, as the receipt of >>>> b.js blocks page layout. As another example, consider images styled >>>> with display: none; once such styling is discovered during parsing, >>>> associated image transfers should be deferred to prioritize visible content. >>>> - Reacting to user behavior >>>> Suppose a SPDY proxy is servicing multiple users. In this case, >>>> many tabs (and their associated streams) are multiplexed over the same SPDY >>>> connection. Fixed priorities (i.e., unchanging over the lifetime of a >>>> stream) preclude reacting to user behavior; e.g., a user may switch among >>>> concurrently loading tabs. >>>> - Server push >>>> No single fixed priority is appropriate for server push. A stream >>>> pushing a large image, for example, should have lower priority than JS/CSS. >>>> But, when pushing JS/CSS that the browser needs, those stream should have >>>> high priority. >>>> >>>> >>>> In sum, for many common scenarios, fixed priorities are not sufficient >>>> to optimize the allocation of bandwidth among competing requests. >>>> >>>> Protocol changes >>>> To address the limitations of priorities, we propose expressingdependencies among streams. >>>> Dependencies improve matters in two main ways: >>>> >>>> 1. Dependencies more accurately reflect the constraints of the >>>> browser. >>>> Rendering a page is a streaming process that naturally leads to a >>>> series of dependencies among resource transfers. For example, a script may >>>> block HTML parsing, and a final layout may depend on an external stylesheet. >>>> 2. Dependencies can be updated efficiently. >>>> The relative importance of streams may change as Javascript >>>> executes or a user changes tabs, for example. Dependencies allow the >>>> browser to express these changes compactly. If a user changes tabs, for >>>> example, the browser may simply signal a change in priority of the tab's >>>> dependency root, thereby reducing (or increasing) the bandwidth allocated >>>> to all dependent transfers. >>>> >>>> >>>> Dependencies are expressed in two ways: 1) a new dependency field in >>>> the SYN_STREAM message, and 2) a new REPRI message that updates the >>>> dependency pointers of existing streams. To allow servers to advertise >>>> their support for scheduling transfers based on dependencies, we propose a >>>> new SETTINGS id/value pair. We describe the layout and semantics of >>>> each in turn. >>>> >>>> Note that these protocol changes are defined in terms of the latest >>>> version of the SPDY draft specification<http://grmocg.github.com/SPDY-Specification/draft-mbelshe-httpbis-spdy-00.html> >>>> . >>>> >>>> SYN_STREAM: >>>> 0 1 2 3 4 5 6 7 >>>> >>>> +--------+--------+--------+-|-------+--------+--------+--------+--------+ >>>> | Length(16) |Flags(8)|1| Stream Id(31) | >>>> 0x1 | -> >>>> >>>> +--------+--------+--------+-|-------+--------+--------+--------+--------+ >>>> >>>> 8 9 10 11 12,13,14..N >>>> +-+-------+--------+--------+--------+=========================+ >>>> |P| PriOrDep(31) | Name/Value Header Block | >>>> +-+-------+--------+--------+--------+=========================+ >>>> >>>> Here, the first 8 bytes are the standard control frame header (§2.2.2<http://grmocg.github.com/SPDY-Specification/draft-mbelshe-httpbis-spdy-00.html#ControlFrames>). >>>> A new 32 bit field replaces the existing SYN_STREAM priority bits ( >>>> §2.6.1<http://grmocg.github.com/SPDY-Specification/draft-mbelshe-httpbis-spdy-00.html#SYN_STREAM>) >>>> with: >>>> >>>> >>>> - P: A bit indicating whether the following PriOrDep bits specify a >>>> priority (P = 1) or a stream ID (P = 0) on which this new stream >>>> depends. >>>> - PriOrDep: Depending on the value of P, either the priority of the >>>> new stream or a stream ID on which this new stream depends. >>>> - The structure and semantics of the Name/Value header block ( >>>> §2.6.11<http://grmocg.github.com/SPDY-Specification/draft-mbelshe-httpbis-spdy-00.html#HeaderBlock>) >>>> are unchanged. >>>> >>>> >>>> P is exclusive; a stream may be assigned a priority or a parent >>>> dependency upon creation, but not both. There are no constraints of the >>>> value of PriOrDep; any 31 bit value is valid. Thus, a stream may refer >>>> to a dependency identifier that does not correspond to any current or >>>> previous stream ID. This is a deliberate design choice that increases >>>> flexibility for clients when structuring dependencies, a topic we expand >>>> upon in the policies section<https://docs.google.com/a/google.com/document/d/1pNj2op5Y4r1AdnsG8bapS79b11iWDCStjCNHo3AWD0g/edit#bookmark=id.6ii1fem7qsws> >>>> . >>>> >>>> Server push streams are assigned an initial parent at the discretion of >>>> the server. A conformant implementation SHOULD create a dependency on the >>>> push stream's associated-to-stream-id (§3.3.1<http://grmocg.github.com/SPDY-Specification/draft-mbelshe-httpbis-spdy-00.html#anchor20> >>>> ). >>>> >>>> REPRI: >>>> 0 1 2 3 4 5 6 7 >>>> >>>> +--------+--------+--------+-|-------+--------+--------+--------+--------+ >>>> | Length(16) |Flags(8)|1| Dependency Id(31) | >>>> 0xc | -> >>>> >>>> +--------+--------+--------+-|-------+--------+--------+--------+--------+ >>>> >>>> 8 9 10 11 >>>> +-+-------+--------+--------+--------+ >>>> |P| PriOrDep(31) | optionally followed by: >>>> +-+-------+--------+--------+--------+ >>>> >>>> DependencyPriOrDep pairs, where a DependencyPriOrDep pair is: >>>> >>>> >>>> +-|-------+--------+--------+--------+-|-------+--------+--------+--------+ >>>> |X| Dependency Id (31) |P| PriOrDep(31) >>>> | >>>> >>>> +-|-------+--------+--------+--------+-|-------+--------+--------+--------+ >>>> >>>> As in SYN_STREAM, the control frame header is standard, followed by a >>>> P/PriOrDep label indicating an update to the 31 bit Dependency Id specified >>>> in the header. We relabel the typical Stream Id here as Dependency Idsince a dependency need not correspond to an actual stream. (Recall that >>>> any 31 bit value is a valid dependency identifier.) >>>> >>>> To support batched updates of dependencies, an optional list of >>>> DependencyPriOrDep pairs with identical semantics may follow. The >>>> number of such pairs is determined by examining the frame length. >>>> number-of-pairs = ((length - 12) / 8). (12 required bytes, 8 bytes from >>>> len(stream_id) + len(PriOrDep)) >>>> >>>> We expect most streams to have at most a single dependency, but this is >>>> not a protocol requirement. (Later, we describe scenarios where multiple >>>> parents may improve efficiency.) If a stream is referenced more than once >>>> in a single frame, this indicates multiple parents. A server implementation >>>> which does not support multiple parents MUST use the last referenced >>>> parent. Clients which send multiple parents thus SHOULD put the most >>>> important parent last. >>>> >>>> SETTINGS: >>>> Recall that dependencies and priorities are advisory. While servers >>>> must accept the messages, they are not required to incorporate them into >>>> scheduling decisions. A client may benefit from knowing a server's level of >>>> support; e.g., a client may specify priorities only if it knows a server >>>> will ignore dependencies. To communicate this, we propose a new >>>> SETTINGS ID/value pair (§2.6.4<http://grmocg.github.com/SPDY-Specification/draft-mbelshe-httpbis-spdy-00.html#SETTINGS> >>>> ), >>>> >>>> >>>> - ID 9 - SETTINGS_MAX_CONCURRENT_DEPENDENCY_SCHEDULING_NODES allows >>>> the server to indicate resource limits for dependency scheduling, e.g., to >>>> limit memory consumption. A value of 0 indicates that the server does not >>>> support dependency scheduling. (We expect most implementations will select >>>> a value greater than or equal to MAX_CONCURRENT_STREAMS.) >>>> - ID 10 - SETTINGS_DEPENDENCY_SCHEDULING_NODE_TIMEOUT indicates how >>>> long the server will maintain dependency nodes after creation. The value is >>>> an interval in milliseconds. This allows the client to estimate if >>>> previously created dependency relationships are still available for >>>> reference at the server. (We expect conformant implementations to maintain >>>> dependencies for at least as long as associated streams are active, >>>> although this is not a correctness requirement.) >>>> >>>> >>>> Both of these values are advisory. Servers need not abide by their >>>> stated values and clients may disregard them. Conformant clients should >>>> respect the concurrency limit, but servers must be robust to a client that >>>> exceeds it. Similarly, servers may drop dependency information at any time >>>> regardless of previous statements made in SETTINGS. This is intended >>>> to provide flexibility for service policies; e.g., a server may reduce the >>>> timeout in response to memory pressure or abandon dependency scheduling >>>> entirely. >>>> >>>> Examples / use-cases revisited >>>> The combination of dependencies and priorities suffices to express >>>> serialized as well as concurrent transfer schedules. (Both are necessary, >>>> as we describe below.) But, how should the browser choose dependencies and >>>> priorities when making requests? This question is best answered >>>> quantitatively, but as a starting point, we consider the following policy >>>> in our examples: >>>> >>>> >>>> 1. Resource dependencies are (re)configured to reflect >>>> parser-blocking order. The transfer of non-streaming resources is always >>>> serialized; i.e., non-async scripts and styling. >>>> 2. Resources that can be progressively rendered (e.g., images) are >>>> transferred concurrently and (re)configured to depend on parser-blocking >>>> resource transfers. >>>> 3. To ensure that the speculative parser can maintain enough >>>> in-flight requests to fill pipe between the client and server, page HTML is >>>> always a top-level dependency, although it may have lower priority than a >>>> resource transfer currently blocking document parsing. >>>> >>>> >>>> When scheduling transfers, we consider a server that allocates >>>> bandwidth hierarchically within dependency trees and splits equallyamong streams with the same parent. >>>> >>>> Concretely, suppose a SPDY connection is multiplexing multiple tabs >>>> from a user connected to a SPDY proxy, with parent pointers and priorities >>>> as shown below. (P6, for example, indicates a priority of 6.) >>>> >>>> To color in this example, suppose that Tab 1 is the foreground tab, >>>> loading in parallel with Tab 2 in the background. Thus, its relatively >>>> higher weight. a.js and b.js are scripts required for the first tab >>>> and should be transferred serially (as scripts are executed in the order >>>> they are declared in the document, and are not parsed until transfer >>>> completes.) Thus, a.js depends on b.js depends on tab1.htm. In the >>>> background tab, two image transfers share capacity as both can be rendered >>>> progressively. Both image transfers have the same parent and hence transfer >>>> concurrently. >>>> >>>> Because the streams associated with the transfers of tab1 and tab2 have >>>> no parent, they are always scheduled before any lower level in their trees. >>>> But, bandwidth allocation among trees remains proportional as defined by >>>> the relative priority of roots. For example, if the transfer of >>>> tab2.htm is in progress and tab1.htm (now complete) is selected, a.jswill be scheduled before >>>> tab2.htm completes. This process proceeds until all transfers in a >>>> tree have completed. >>>> >>>> As a practical matter, the timeout for pruning nodes in a tree should >>>> be selected to allow transfers to complete and to allow clients to name >>>> currently completed parents when defining transfer dependencies. >>>> Concretely, on a high delay path, a small HTML transfer may be flushed >>>> entirely by the server before the client receives any data and begins >>>> making dependent requests for resources embedded in the page. >>>> >>>> With these client and server policies in mind, we revisit the >>>> motivating use-cases described above in greater detail. >>>> >>>> - Specifying an ordering of resource transfers >>>> - Reacting to document parsing >>>> >>>> We illustrate the need for both serial dependencies, concurrency, and >>>> reprioritization in these cases with a simple example. >>>> >>>> Suppose site.com has index.htm: >>>> <html> >>>> <body> >>>> <script src="a.js"></script> >>>> <img src="a.jpg" width="100" height="100"/> >>>> <img src="b.jpg" width="100" height="100"/> >>>> <link rel="stylesheet" type="text/css" href="style.css"> >>>> </body> >>>> >>>> with a.js: >>>> document.write('<script src="b.js"></script>'); >>>> >>>> b.js: >>>> document.write('<div>blocker</div>'); >>>> >>>> and style.css: >>>> div { >>>> border: 1px solid #000; >>>> } >>>> >>>> How would this example page be transferred today? As the main HTML is >>>> received and parsed, a request for a.js will be issued and block the >>>> document parser. As the remaining HTML streams in, the speculative parser >>>> will issue requests for a.jpg, b.jpg, and style.css in quick succession. >>>> Once a.js is received and executed, a request for b.js will be issued, >>>> which again blocks parsing until received. Visually: >>>> >>>> >>>> This transfer schedule is suboptimal. Page rendering will complete only >>>> when style.css and b.js have completed, but receiving each of those >>>> critical resources is slowed by competition for bandwidth capacity with >>>> bulk data that's not on the critical path (a.jpg and b.jpg). >>>> >>>> What we would like is serialized transfer that reflects the document >>>> parse order with concurrency for nonblocking, streaming resources. More >>>> specifically, we want to receive: 1) index.html, 2) a.js, 3) b.js, and 4) >>>> style.css serialized (i.e., with no deliberate sharing of capacity among >>>> the ordered transfers). After those critical transfers have completed, >>>> a.jpg and b.jpg should be transferred concurrently (as they may be >>>> displayed progressively.) >>>> >>>> Folding in the protocol mechanisms described above: >>>> >>>> >>>> In the figure, each resource request corresponds to a new SPDY stream >>>> with the form ID: reqest (PriOrDep). In more detail: >>>> >>>> >>>> - The SYN_STREAM for the index.htm request has a parent indicating >>>> a default priority (3) and a stream id of 1. >>>> - The document parser is blocked once the external script a.js is >>>> parsed. At this point, the speculative parser looks ahead and creates new >>>> streams for a.jpg, b.jpg in parse order. a.jpg and b.jpg can be >>>> progressively rendered, so their transfer is concurrent (same parent, 2, >>>> corresponding to a.js). >>>> - When the parser encounters style.css, back-to-back control >>>> messages are sent to create the stream and update the dependencies of the >>>> image transfers. Since stylesheets block rendering and cannot be streamed, >>>> the image transfers are updated to depend on style.css (P5). >>>> - Once a.js completes, the document parser continues, executing >>>> a.js and inserting b.js via document.write(), again blocking >>>> document parsing on the receipt of b.js. At this point, b.js should preempt >>>> all other transfers since it's a non-streaming resource that is blocking >>>> page rendering. To this end, the client creates the b.js stream with a.js >>>> as its parent (or, equivalently, index.htm). Batched with this >>>> SYN_STREAM is another REPRI message rewiring style.css to depend on >>>> b.js. This serializes the transfers (modulo the delay associated with >>>> message propagation and any transfer buffering delay at the server). >>>> >>>> >>>> This transfer schedule may significantly improve performance. By >>>> serializing the transfer of resources on the critical path, the browser can >>>> ensure that resources needed immediately do not compete for bandwidth >>>> capacity with less important transfers. Yet, the pipe remains full, as a >>>> queue of requests is maintained in the scheduling tree ready to fill any >>>> idle capacity with useful data. Where we cannot make an informed scheduling >>>> decision, we hedge our bets with concurrent transfers by hinting that they >>>> are peers and letting the server decide what makes the most sense --- as in >>>> the case of two above the fold images that can be rendered progressively. >>>> >>>> Note that this sort of explicit scheduler hinting is not possible in >>>> HTTP today. Requests, once issued, cannot be reprioritized or reordered on >>>> a single connection. This results in suboptimal transfer schedules given >>>> the limitations of HTML lookahead scanning. Yet, lookahead is essential for >>>> ensuring the concurrency necessary to keep the client <-> server pipe full. >>>> While the browser might serialize transfers itself, the many small >>>> transfers typical of pageloads would significantly limit utilization. With >>>> ordering and reprioritization in SPDY, browsers can jointly optimize both >>>> the transfer pipeline and resource priority as desired, rather than >>>> being forced to accept poor utilization or poor transfer schedules. >>>> >>>> - Servicing multiple tabs/users over a single SPDY session >>>> As an illustration of this case, recall the example from our straw-man >>>> design: >>>> >>>> >>>> Suppose concurrent tabs are loading with a scheduling forest as shown. >>>> When a user changes tabs, the browser simple sends a REPRI for the >>>> stream associated with tab2.htm to, say, priority 8. (A batched message >>>> might also reduce the priority of tab1.htm to weight 3.) Because bandwidth >>>> allocation decisions are made tree-by-tree and level-by-level, increasing >>>> the priority of tab2.htm effectively shifts capacity for all resource >>>> transfers depending on tab1.htm to tab2.htm. >>>> >>>> - Server push >>>> As in client SYN_STREAM messages, server push messages indicate the >>>> priority and dependencies of a resource as chosen by the server. Much >>>> like the client, the server is free to adopt prioritization policies to >>>> improve performance, e.g., by prioritizing pushes of styles over images. >>>> But, as in our example above, the browser may update the server's choices >>>> as information about resources needed for parsing is learned. (Again, >>>> expressed via REPRI messages.) >>>> >>>> Policy considerations >>>> Both priorities and stream dependencies are advisory hints. Browsers >>>> may adopt sophisticated policies or leave dependencies entirely >>>> unspecified. Similarly, servers may incorporate dependency hints into very >>>> sophisticated schedulers or ignore them entirely. The protocol >>>> mechanisms for encoding dependencies are designed to be simple. But, >>>> these mechanisms afford a very flexible set of policies depending on how >>>> browsers and servers use them. This section expands on several policy >>>> considerations. >>>> >>>> Assigning and updating dependencies. >>>> Updates and overhead >>>> In our examples, we consider a browser that configures dependencies to >>>> reflect parser-blocking order for resources, updated as parsing continues. >>>> We expect this to improve performance, but browsers are free to deviate >>>> from this policy, and there may be good reasons to do so. For example, if >>>> the parser-blocking order is highly dynamic (e.g., in response to many JS >>>> events), the overhead of updating dependencies may not be worth the cost, >>>> particularly for small transfers. A sophisticated client may base >>>> dependency update decisions on content-length and/or RTT, restricting >>>> updates to only those streams likely to benefit from it. Quantitative >>>> implementation experience will be helpful here. >>>> >>>> The overhead of updating dependencies depends in part on the existing >>>> structure of dependencies. In some scenarios, it may be more efficient to >>>> introduce placeholder nodes to improve the efficiency of common update >>>> operations. For example, consider a variant of our earlier example page: >>>> >>>> <html> >>>> <body> >>>> <script src="a.js"></script> <!-- containing: document.write('<script >>>> src="b.js"></script>'); --> >>>> <img src="1.jpg" width="100" height="100"/> >>>> <img src="2.jpg" width="100" height="100"/> >>>> <img src="3.jpg" width="100" height="100"/> >>>> ... >>>> <img src="10.jpg" width="100" height="100"/> >>>> </body> >>>> >>>> In this example, the speculative parser might create 10 streams >>>> depending on the JS transfer; i.e., >>>> >>>> But, once a.js is executed, the transfer of b.js should preempt all >>>> image transfers; i.e., >>>> >>>> Transitioning between these dependency structures requires sending >>>> REPRI messages for each image. Because updating the dependencies of >>>> images is common, a client might create all image streams with a >>>> placeholder dependency, yielding an initial configuration of: >>>> With such an initial configuration, updating the dependencies of the >>>> images to the stream associated with b.js can be accomplished with a single >>>> REPRI message updating the placeholder. >>>> >>>> Multiple parents >>>> >>>> ... > >
Received on Sunday, 3 November 2013 23:22:18 UTC