Subject: Re: [quicwg/base-drafts] PRIORITY frame on control stream referencing unopened request stream (#2502)

From: Mike Bishop <[email-masked]>
Date: Tue, 07 May 2019 11:53:04 -0700

I don't think simple buffering is sufficient.  You would have to not only buffer the frame that updates the priority of a not-yet-created stream, but also frames that create dependencies on that stream, and frames that create dependencies on streams that would be under that tree if you weren't already buffering the frames that create the tree.  That can be done, but it's not straightforward.

A simpler alternative is, potentially, to stop processing PRIORITY frames (which effectively means not processing the control stream) until the indicated stream has arrived.  Not great, but PRIORITY frames are most of what will be on that stream and we've already said they need to be processed in order.

I don't feel like there's a good solution to this and I'm supportive of exploring alternative priority mechanisms, but I'm not sure that needs to land in the core H3 spec.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/2502#issuecomment-490211531

---

From: Martin Thomson <[email-masked]>
Date: Tue, 07 May 2019 16:45:36 -0700

That suggests the creation of a "priority" stream...

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/2502#issuecomment-490293901

---

From: Lucas Pardue <[email-masked]>
Date: Tue, 07 May 2019 17:45:04 -0700

A priority stream, in our current scheme, has some desireable properties because it aligns with the asymmetry, i.e. only client can create a priority stream. If anyone cared you could borrow QPACK encoder/decoder model so that the client has clear indication when priorities were processed. One could go as far as adopting that model further, 

1) priority stream(s) contains unframed instructions
2) PRIORITY frame on request is just a shell that contains references to priority state.

This opens a possibility to have alternative priority schemes based on opening different types of priority streams.

It all sounds terribly complicated though :D

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/2502#issuecomment-490304852

---

From: Martin Thomson <[email-masked]>
Date: Tue, 07 May 2019 17:49:39 -0700

Not really complicated.  Possibly less complicated, especially if you consider that dropping the priority stream could be permitted if it were separated from SETTINGS.  And SETTINGS could get its own stream too :)

I wouldn't go so far as to say unframed priority signals, but the possibility to dispense with framing is appealing to some extent.  Complicated comes when you have a marked in a stream saying what priority state you are depending on.  That wouldn't necessarily be a blocking signal in the same way that QPACK is, but it certainly drives complexity upward slightly.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/2502#issuecomment-490305639

---

From: Lucas Pardue <[email-masked]>
Date: Wed, 08 May 2019 01:09:56 +0000 (UTC)

> Not really complicated. Possibly less complicated, especially if you consider that dropping the priority stream could be permitted if it were separated from SETTINGS. And SETTINGS could get its own…

tangential thought: why bother with a stream for a one-time-shot frame. Right now H3 has a weirdness around the H3 connection not being "initialized" until SETTINGS have been sent. It might be more suitable to have a transport-level frame (within the packet protection boundary) that can carry application-defined handshake messages.   

sorry for derailing

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/2502#issuecomment-490309068

---

From: Kazuho Oku <[email-masked]>
Date: Tue, 07 May 2019 20:10:15 -0700

@MikeBishop 
> I don't think simple buffering is sufficient. You would have to not only buffer the frame that updates the priority of a not-yet-created stream, but also frames that create dependencies on that str…

I second @dtikhonov's view that the current mechanism is simple enough.

What you need to do (i.e. what I do) is create a priority node (with a given ID) when receiving a PRIORITY frame that first refers to that ID. When receiving a request stream is opened, the server looks if a priority node already exists. If it does, that is used.

The node also has a `implicitly_initialized` flag, that indicates if a PRIORITY frame received on a request stream should be respected. The flag is set when a priority is received for the first time for the given node, but not when a node is created due to being referred to by PRIORITY.element_dependency.

If we are to discuss alternative designs, I'd argue that providing the server the priority information at the moment it receives a request should be a requirement (at least for the Firefox-style dependency tree, which I think we agree as the optimal design). Otherwise, we'd be risking H3 performance becoming inferior to H2 due to increased chance of mis-prioritization.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/2502#issuecomment-490330136

---

From: Mike Bishop <[email-masked]>
Date: Wed, 08 May 2019 09:00:09 -0700

To be clear, I'm not advocating for a more complicated scheme than what we have now -- I think that your implementation sounds very reasonable.  The issue as filed, however, describes that implementing that way creates (hopefully brief) misprioritizations before consistency is achieved:  when something has `implicitly_initialized` set, what priority is given to it, or more relevantly, to its children?  I'm arguing that solving these misprioritizations is more complex than suggested.

I think our choices are:

- Live with the misprioritizations -- what we have is fine
- Block processing of priority instructions entirely when an uncreated stream is encountered as a dependency -- better to delay updates than get things wrong
- Totally replace the priority scheme before RFC

I continue to believe the latter is probably out of both scope and time for this working group, unless HTTPbis directs us otherwise.

The discussion of moving to more unidirectional stream types is largely orthogonal to this choice; I'm going to suggest we take it to a separate issue and decide that independently.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/2502#issuecomment-490545898

---

From: Mike Bishop <[email-masked]>
Date: Wed, 08 May 2019 09:19:07 -0700

Also note that this is not really normative -- we're recommending an implementation option, and we could recommend both as options to be considered.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/2502#issuecomment-490552820

---

From: Kazuho Oku <[email-masked]>
Date: Wed, 08 May 2019 16:36:29 -0700

Thank you for the clarifications.

> when something has implicitly_initialized set, what priority is given to it, or more relevantly, to its children? I'm arguing that solving these misprioritizations is more complex than suggested.

In my implementation, implicitly-initialized nodes are associated to the root with weight set to 16. I agree that we have the chance of misprioritization here, and that we do no specify how servers should handle that. I also think that what my implementation does now is not optimal - if we are to learn from the lesson of HTTP/2 that some servers respect only the weights but not the structure of the tree, the server should consider children of implicitly-initialized nodes as direct descendants of the root with their respective weights, until the PRIORITY frame for the implicitly-initialized node is received.

That said, I am not too worried about the status quo, due to the following reasons:
* We are encouraging (or we should encourage) web browsers requesting HTML and assets to use Firefox-style dependency tree. That means that chance of misprioritization only exists during the exchange of very first flights when the PRIORITY frames for the placeholders are sent.
* For video streaming, daisy-chaining of streams is preferable. But because we can expect several round-trips to be spent between each request, misprioritization would not be an issue in practice.

> I continue to believe the latter is probably out of both scope and time for this working group, unless HTTPbis directs us otherwise.

+1. I also agree that it would be beneficial to call out the strategy (or strategies) that the servers might employ, and if necessary the side-effects of those strategies that the clients should take into consideration.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/2502#issuecomment-490689310

---

From: Robin Marx <[email-masked]>
Date: Thu, 09 May 2019 00:51:24 -0700

Thank you all for the insightful comments :) 

I guess my main gripe is maybe with the "default" behavior of adding the node as a direct child to the root of the tree. As we have found in our research (1) (and many others besides) this default behaviour (equal weighted round robin) is (by far) the worst behaviour you can get in a web browsing context. A first-come-first-served setup is better in almost every way. 

A simple compromise might be to change the default behaviour from "add to root with weight 16" to "**add as direct child of the last added node (could be root) with weight 1**" or something similar. This also has plenty of caveats and edge cases, but afaict should give better results in cases where lots goes wrong at the same time (e.g., fast link and high current cwnd with sudden burst of lost priority frame(s)). This would imo greatly reduce the potential impact of an "implicitly_initialized" node in the most common case (lots of higher-priority requests outstanding, which you would interfere with by adding to the root instead). 

> +1. I also agree that it would be beneficial to call out the strategy (or strategies) that the servers might employ, and if necessary the side-effects of those strategies that the clients should ta…

I am also 100% for this. 

With regards to the alternate priority schemes/changing before RFC: afaict, Pat Meenan's proposal can be implemented using an extension frame (replacing the "normal" PRIORITY frame). At least that's how we are planning on starting to experiment with it soon. In that case, a more complex setup with the unidirectional priority streams etc. might be overkill (sorry @LPardue ;) Anyone think that's not possible?

TL;DR I would be in preference of keeping things as they are in general, but changing the default behavior for non-explicitly-prioritized streams. 

(1): https://speeder.edm.uhasselt.be/www18/

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/2502#issuecomment-490792254

---

From: Kazuho Oku <[email-masked]>
Date: Thu, 09 May 2019 12:01:40 -0700

@rmarx Thank you for your comments and for the fantastic research (maybe I should have said this earlier)! 

I think we are really discussing two issues here: a) how the server should behave when the client does not provide priority information at all, and b) when priority information is not available due to a packet loss. To resolve both the issues (I do share the concerns), maybe we should better have two different issues opened for each.

For _b_ (which IIUC is the original topic of this issue), I would argue the following.

As a general statement, mis-prioritization happens until the lossed packet is retransmitted and received. Therefore, the impact is small.

That said, if the client uses Firefox-like prioritization scheme (i.e. grouped by placeholders), it is fair to assume that unresolvable nodes appear only during the very early stages of the connection. During that time, there is higher probability of receiving a request that should be given higher priority than than the precedence requests (i.e. request for CSS arriving after request for HTML). That's very different from what you see in later moments (i.e. requests for things like images and async javascript files arrive, that require lower priority).

If the client uses Chrome-like prioritization scheme (i.e. daisy chaining), I now think that we should recommend the client to send a PRIORITY frame on the request stream to specify the parent node, _and also transmit the same information by sending a PRIORITY frame on a control stream_, then sending another PRIORITY frame to indicate that a sibling is converted to a child of the newly created node. By transmitting the same information on both streams, the server would never see an unresolvable node in the prioritization tree. So why not recommend clients do that, instead of trying to figure out how the server should compensate for the lack of the information?

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/2502#issuecomment-491026561

---

From: Kazuho Oku <[email-masked]>
Date: Thu, 09 May 2019 12:10:25 -0700

PS. My bad, the solution for the Chrome-like prioritization scheme only works when inserting one node in the middle of the chain, but does not work when the client wants to insert multiple nodes at once. I really think we should discourage clients creating many daisy-chained objects at once...

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/2502#issuecomment-491029316

---

From: ianswett <[email-masked]>
Date: Thu, 09 May 2019 12:41:40 -0700

Chrome is only doing indefinitely longs lists because H2 doesn't have strict priorities.  With strict priorities, everything becomes simpler.

Discouraging super-long lists is the wrong direction from an optimal browser/app loading perspective.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/2502#issuecomment-491038822

---

From: Kazuho Oku <[email-masked]>
Date: Thu, 09 May 2019 12:58:37 -0700

While I agree that response serialization is beneficial for some types of resources (e.g., for JavaScript, because each file cannot be executed until the entire file is being received), it is my understanding that response serialization of images - the most common type of resource being fetched - is a bad idea, because it goes against progressive rendering.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/2502#issuecomment-491044130

---

From: ianswett <[email-masked]>
Date: Thu, 09 May 2019 13:20:48 -0700

Patrick Meenan knows more about this than I do, but I think the ability to evenly round robin between resources at a given priority value is sufficient, given that's what he recently proposed in https://lists.w3.org/Archives/Public/ietf-http-wg/2019JanMar/0073.html

I have a hard time imagining a browser that would be able to pick a better weight than equal weighting for images.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/2502#issuecomment-491051373

---

From: Patrick Meenan <[email-masked]>
Date: Thu, 09 May 2019 13:48:24 -0700

Getting JavaScript and CSS "right" tends to have more of an impact on the initial page render and app interaction (faster first paint) even though there are fewer of them than images. Interlacing images works well for progressive image formats but not for, say, SVG's (though those tend to be tiny - PNG's on the other hand can be huge).

IMHO, an optimal ordering looks something like this:
- Serialize the CSS and blocking JS in the head
- Load the visible images in parallel (simple round robin)
- Serialize async (and late-body) JS and load them in parallel with non-visible images. The non-visible images might be better to serialize in document order for long-scroll pages instead of loading ALL of them in parallel

If you're going to pick a default, a sequential list works much better than parallel, otherwise you get all of the images stealing bandwidth from the CSS/JS and delaying the initial render. The downside in that case is images loading one at a time instead of concurrently but it's much better than the no-render case.

Discovering when something is "visible" changes over time which is the main reason reprioritization is critical.

As far as late-loading high-priority resources go, Fonts are probably the clearest example since they are not discovered until layout and by the time they are discovered they are needed pretty much immediately to render the text.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/2502#issuecomment-491060502

---

From: Kazuho Oku <[email-masked]>
Date: Thu, 09 May 2019 14:44:21 -0700

@pmeenan Thank you for the insights. I think we all agree on what the optimal ordering is.

I think there are three questions:
* How important is it to have serialization _within_ the blocking assets? It is beneficial to deliver blocking JavaScript files one by one rather than doing RR among them, because giving the client to execute _some_ JavaScript_ files earlier helps. However, the question is how much it helps, because I'd assume that in the common case a browser cannot render anything until all the blocking JavaScript files arrive.
* How important is it to have strict serialization between blocking assets vs. images, compared to having 256n:1 distribution where N is the number of blocking assets (i.e. the Firefox approach).
* If we consider either of the above two to be important enough that daisy-chaining is necessary, there'd be chance of having small mis-prioritization windows due to packet loss (the topic of this issue), not only at the very beginning of the connection but every time more than one request is inserted per one RTT. Is that something we need to fix?

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/2502#issuecomment-491079825

---

From: Patrick Meenan <[email-masked]>
Date: Thu, 09 May 2019 15:04:52 -0700

Serialization within the blocking assets can help quite a bit because the download, parse and eval can be pipelined. If they download in parallel then all of the execution gets batched up after they finished downloading.

"Strict" serialization between blocking and images may not be necessary as long as the ratios are high enough that it is "effectively" serialized. If I recall, the Firefox tree weights the split between groups as 200:100 (for non leader/follower) which isn't enough to pull off effective serialization but it can certainly be done with something like the Firefox tree. If each group could be tagged as round-robin vs serialized it could eliminate the need to build a deeper tree.

Small windows are fine, it's all best-effort anyway otherwise we get HOL blocking. That said, inserting 1 resource per RTT seems like it would be a problem if the RTT's are all serialized. If the cost to boost priority was 1 RTT per resource but they could all be done in parallel it would be fine. Something like a 200-resource page with a 100ms RTT is 20 seconds to prioritize all of them.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/2502#issuecomment-491085085

---

From: Kazuho Oku <[email-masked]>
Date: Thu, 09 May 2019 16:30:33 -0700

Thank you for the answers. Your observations sound right to me.

>  If each group could be tagged as round-robin vs serialized it could eliminate the need to build a deeper tree.

That's definitely one way going forward, though I think we'd lose the ability to express certain types of trees that can be represented in HTTP/2.

> If the cost to boost priority was 1 RTT per resource but they could all be done in parallel it would be fine.

This would be the case. And the cost is incurred only when there is a packet loss. To be precise, there would be 1 RTT penalty to synchronize the prioritization tree for every loss event of a packet carrying PRIORITY frame.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/2502#issuecomment-491102667

---

From: Patrick Meenan <[email-masked]>
Date: Thu, 09 May 2019 17:03:52 -0700

> This would be the case. And the cost is incurred only when there is a packet loss. To be precise, there would be 1 RTT penalty to synchronize the prioritization tree for every loss event of a packe…

That wouldn't be a problem at all. You'd likely get more interruption than that in HTTP/2 if a TCP packet anywhere near a PRIORITY frame got dropped anyway.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/2502#issuecomment-491108296

---

From: Kazuho Oku <[email-masked]>
Date: Thu, 09 May 2019 18:44:21 -0700

> That wouldn't be a problem at all. You'd likely get more interruption than that in HTTP/2 if a TCP packet anywhere near a PRIORITY frame got dropped anyway.

Yeah. That's definitely a good and conservative way to think of the issue. And I presume that such perception would lead to what @rmarx has suggested in https://github.com/quicwg/base-drafts/issues/2502#issuecomment-490792254; i.e. assign the lowest possible precedence to requests that have yet-to-be-known priority.

I think I now agree with @rmarx that that could be the recommendation, if we are to recommend something in the specification.

That said, I think I would try to let the server "guess" the correct priority, because doing better than HTTP/2 when packet loss is involved _is_ the primary motivation of doing HTTP/3, and therefore my preference goes to clarifying in the specification that such fiddling is allowed, if we are to recommend something.

One way of making such a guess would be to check the content-type of the response. Another way would be to use the "weight" of the request stream (even though it is unknown how it is connected to the root of the prioritization tree).

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/2502#issuecomment-491124286

---

From: Robin Marx <[email-masked]>
Date: Fri, 10 May 2019 03:48:50 -0700

Again, thanks everyone for the interesting discussion and Pat for weighing in :) 

I've been thinking about it a bit more and have found that my earlier suggestion "add as direct child of the last added node (could be root) with weight 1" simply does not work... 

To make discussion easier, I've made a small diagram:
![exclusivity_problems](https://user-images.githubusercontent.com/2240689/57520389-d36ea380-731d-11e9-825a-106553366ef3.png)

In S5 you can see that such a scheme would create a circular dependency for a (short) time. 

I've been considering it further and these are possible options that do seem to work and might be better:
- Add as child to the root with weight 1 instead of 16
- Add as child to the "least important placeholder" with weight 1 (e.g., the placeholder receiving the least bandwidth) if there are placeholders, if not: fallback to root. (this assumes placeholders always remain and always have some path back up to the root)
- Add as child to the currently "most important resource" (resource receiving most bandwidth): non-optimal and can lead to weird situations, BUT at least prevents the most important resource from being interrupted (e.g., in the example, this would add the red node as child of the HTML, since that is the one getting the bandwidth). 

We could also do all three (first try placeholder, then try resource, then fall back to root). 
This could use a fair amount more of working out the edge cases though

---------------------------------------------------------------------------------------

Then, I took a step back and thought about: do we really need exclusive priorities? 
The main goal is to keep the option to daisy-chain resources. This is still possible today: just add as a child to another resource. 
What we miss with non-exclusivity is the option to then re-prioritize when a new, more important resource needs to be inserted in the daisy-chain (it cannot be injected somewhere in the middle as an only child, only as a sibling, see also the HIGHEST-subtree in P3 and P4 in the image below for a similar situation). 

As I understand it though, this re-prioritization is **not needed within similarly important resources** (e.g., CSS does not have to necessarily overtake Fonts, just images). 
Using that, I've tried to cobble together a new scheme that simulates Chrome's approach using what we have available today (see P2 in the image below): 
![exclusivity_light](https://user-images.githubusercontent.com/2240689/57521628-18480980-7321-11e9-8aa9-842d62744fc3.png)

This setup allows re-prioritization between the placeholders, but **not** within the same "importance bucket": less fine-grained than exclusive priorities, but quite workable. (e.g., in P4+5, CSS is discovered later, after the image. However, due to the placeholders, it can be added and is sent before the images, but NOT before the font, as was the case in HTTP/2's P3). 

Put differently: we cannot have P3, but at least P5 is not P4. 

---------------------------------------------------------------------------------------

In conclusion:
- Fairly small updates to the default behavior could give us most of the improvements we are looking for
- Daisy-chaining and re-prioritization (within a certain degree of granularity) is still possible in the current scheme

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/2502#issuecomment-491246513

---

From: Kazuho Oku <[email-masked]>
Date: Fri, 10 May 2019 03:59:01 -0700

@rmarx 
> I've been thinking about it a bit more and have found that my earlier suggestion "add as direct child of the last added node (could be root) with weight 1" simply does not work...

I think what you are looking for might be a weight=0 node belonging to the root, that is given bandwidth only when there are no active nodes with a positive weight. When a server has a node that cannot be resolved, it is assigned to the weight=0 node, and then it would naturally be given the least precedence.

Internal representation of the prioritization tree does not need to restricted by the vocabulary defined by the specification.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/2502#issuecomment-491248987

---

From: Robin Marx <[email-masked]>
Date: Fri, 10 May 2019 04:04:29 -0700

@kazuho 
I agree. IIUC that's the first new option I am alluding to (use weight 1 instead of 16 (implementation could use weight "0" internally)).

My previous suggestion was to add it as a child of the "last added node", which is what I mean doesn't work, as it creates potential cyclic dependencies (see S5)

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/2502#issuecomment-491250321

---

From: Lucas Pardue <[email-masked]>
Date: Fri, 10 May 2019 04:22:20 -0700

I think it would not be too much effort to add something that says approximately, for the current scheme: 

"The priority tree always has a root and and one 0-weight placeholder (the zeroth placeholder)". 

Then we modify one of the paragraphs to say:

"When a prioritized element is first created, it has a default initial weight of 16 and a default dependency. Requests are dependent on the zeroth placeholder, placeholders are dependent on the root of the priority tree; pushes are dependent on the client request on which the PUSH_PROMISE frame was sent."

If some other prioritisation scheme were come into play, just replace "dependency" by prioritisation group, or whatever term you like.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/2502#issuecomment-491254708

---

From: Mike Bishop <[email-masked]>
Date: Fri, 10 May 2019 10:54:36 -0700

If we're going to create a placeholder that a) doesn't count toward the placeholder limit b) can't be reprioritized and c) has an impossible-to-express weight, it would be a new special construct.  I'm almost tempted to give it index -1 so that it can't be directly referenced, to further emphasize that it's special.

(As an aside, I was kind of disappointed the proposal to allow zero-weight dependencies with these semantics didn't get any traction back in HTTP/2.)

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/2502#issuecomment-491377093