Profile picture
Alex Russell @slightlylate
, 29 tweets, 9 min read Read on Twitter
@EWErikWitt @igrigorik @yoavweiss @jaffathecake So it's an incendiary title; "Chrome...breaks HTTP/2 priorities!". The effect is real, the cause is misattributed.
@EWErikWitt @igrigorik @yoavweiss @jaffathecake First, note the code for the SW in question; it's not a pure pass-through:

`addEventListener('fetch', event => {

event.respondWith(fetch(event.request));
});`
@EWErikWitt @igrigorik @yoavweiss @jaffathecake That might *look* like a passthrough, but it's not. Calling `fetch()` with a `Request` object implicitly *creates a new Request object*:

fetch.spec.whatwg.org/#fetch-method

(see step 2)
What does this mean in practice? It means the `Request` constructor copies all of the publicly accessible information from the passed-in `Request` object and constructs a new `Request` with that information as it's configuration.

Priority isn't publicly available.
So why isn't priority information available on the `Request`!?!!!!

TL;DR: both the HTML and H/2 specs are bullheadedly promulgating their "one true way" to do priorities and they're both MORONIC.
The HTML spec leaves priorities as an implementation to the reader. Browsers make up whatever they want. The rules are made up and the points don't matter.
Internally, this means that all browsers come up with their own priority schemes and are free to schedule dispatching fetches however they like.
Real-world browsers (like Chrome) have to deal with HTTP 1.1 and 2.0 at the same time. This means that priority doesn't map cleanly onto the H/2 notion of priorities...which is also bonkers. How bonkers? Lets take a look!
Browsers process network fetches roughly in the order they're made aware that they're going to need to issue them. We go to great lengths to find out when we're going to need bits and bobs; we even go so far to implement crazy parser hacks to "read ahead" to find resources faster
@igrigorik's post from '13 goes into some of the details on this: plus.google.com/+IlyaGrigorik/…
So browsers read stream sof bytes coming in and try to locate things that will correspond to network resources and request them early. This is happening in the critical path of page load without full information about the resulting DOM, CSS OM, or even what's in the viewport.
Because networks aren't perfectly fast, outbound requests go into a queue. The way Chrome prioritizes those requests is based on a bunch of heuristics. Did it come from a blocking script? High priority! XHR? Low priority. Etc., etc.
Remember: HTML doesn't actually define a priority system, so this is all an exercise to the implementer and browsers do simulated annealing to come to roughly-good heuristics (historically, based on bogus benchmarks, but we're doing better now; thanks for asking).
So browsers are trying to keep the pipe full. Wasted time in the critical path is wasted time. There's no other word for it. Being slightly wrong about priority is much worse than not issuing a network request with the channel would otherwise be empty.
Let that really sink in: the browser-side idea of priority is a decision made with incomplete information, under the gun, and once the request is sent, it's pretty much over-and-done with.
Contrast that with the baroque-AF priority system that the H/2 WG cooked up at the last minute: http2.github.io/http2-spec/#pr…

Earlier drafts used integer priorities (in a small range, IIRC). The final version, in contrast, assumes the client knows a LOT about outbound requests.
So you've got a server with lots of time (until it gets a flood of requests to handle), assuming a client that has full knowledge of the dependency graph...which as we've just discussed, is basically never the case.
Getting more information to construct a more accurate dependency graph would require more processing (and waiting) on the client side before issuing requests...which is dead air...which is bad. So client's don't actually wait. They take their initial guess about priority and run.
"But", I hear you saying, "the client can adjust priorities!": http2.github.io/http2-spec/#re…

LAWLZ.
In practice, inbound requests dish off to some other thread. That work is likely I/O bound. That I/O, once started, isn't worth pausing or changing. You're better off getting the bytes into memory to be flushed ASAP with as little second guessing as possible.
High-performance H/2 servers will pretty much always drop subsequent PRIORITY frames on the floor and high-performance clients won't wait to generate them.

H/2 priorities are a practical joke as far as I can tell.

I presume @mnot is getting the last laugh.
So what's happening in @EWErikWitt's post is a cruel combination:

1.) HTML has serially failed to define a meaningful priority scheme (yes, I'm grumpy about it)
2.) H/2 priorities aren't passed because it's "magic" info as a result
3.) fetch() is in the XHR slow bucket 😥
@EWErikWitt's post should be titled "Service Workers show how broken HTML and H/2 priorities are". We can do some magic in the limited case he outlines where the source `Request` hasn't been touched, but honestly, we shouldn't.
Instead, we should be exposing a real, integer-range-based, priority system. No, browsers won't magically agree on these weights. Yes, network stack will sometimes need to reorder anyway, but how is that worse than the status quo?
The infuriating part of this is the condescension from the H/2 and network stack community. The fear that web developers will "just make everything high priority; then what?" is both real, true, and useless.
We'll always need to intervene as the user's agent, but so long as JS is part of the platform, developers could *already* do whatevs; it might just have been the long way 'round.
So it's worth flagging this effect, worth being upset, and perhaps even worth calling out all the folks who work on Chrome that haven't fixed it.

But the problem isn't the implementation. It's harder and worse than that. It's a fundamental lack of respect for web developers.
Taking control of the network shouldn't mean always getting down-ranked in priority. This sort of magic needs to be in developer hands:

cs.chromium.org/chromium/src/t…
Missing some Tweet in this thread?
You can try to force a refresh.

Like this thread? Get email updates or save it to PDF!

Subscribe to Alex Russell
Profile picture

Get real-time email alerts when new unrolls are available from this author!

This content may be removed anytime!

Twitter may remove this content at anytime, convert it as a PDF, save and print for later use!

Try unrolling a thread yourself!

how to unroll video

1) Follow Thread Reader App on Twitter so you can easily mention us!

2) Go to a Twitter thread (series of Tweets by the same owner) and mention us with a keyword "unroll" @threadreaderapp unroll

You can practice here first or read more on our help page!

Did Thread Reader help you today?

Support us! We are indie developers!


This site is made by just three indie developers on a laptop doing marketing, support and development! Read more about the story.

Become a Premium Member and get exclusive features!

Premium member ($3.00/month or $30.00/year)

Too expensive? Make a small donation by buying us coffee ($5) or help with server cost ($10)

Donate via Paypal Become our Patreon

Thank you for your support!