Removing HTTP/2 Server Push from Chrome
developer.chrome.com
developer.chrome.com
If you're trying to imply HTTP/2 and HTTP/3 have this goal, then I am glad you are not writing any HTTP libraries. I am sick and tired of everyone rolling their own shoddy, incomplete HTTP/1.1 libraries with string splitting and regex. I safely assume any HTTP library that does not support at least HTTP/2 is exactly this.
I'm glad the "complexity" of HTTP/2 and HTTP/3 means less people are trying to make a half-assed implementation. By the time you get to actually sending stuff with HTTP/3, you'll be deep enough that you won't just forget the whole 3xx series of response codes.
The fact of the matter is that these people will probably still not use HTTP/2, but rather stick with their broken HTTP/1.1 implementation, and therefor forever requiring browsers to support this.
If the technical limits of HTTP/1.1 limit the amount and effectiveness of online advertising and behavourial tracking, or if it limits the amount of time people may potentially waste on the "interactive" attention-grabbing www, then that is a benefit, IMHO. To put it another way, if the technical deficiencies of HTTP/1.1 limit the viability of "tech" companies then this is a benefit, because "tech" companies are responsible for attaching surveillance to commercial and recreational web use that I would prefer not to support.
HTTP/1.1 and below were for a less commercial web not controlled by Google.
Server Push was introduced in HTTP/2. TCP was replaced later, in QUIC and HTTP/3. The goal of replacing TCP was not to improve Server Push. Chrome never even implemented Server Push for HTTP/3.
Disclosure: I work at Google but not on Chrome.
And once talking about all this, the Chrome team is one of the less important parts of Google in bringing about HTTP/2 and HTTP/3.
Yes, HTTP/2 and HTTP/3 are more complex than HTTP/1, but these are not the ways Google is harming the web—these are the good parts of what Google is helping to improve the web.
You are yearning for the simple and inefficient days of yore, but those days are gone. The internet is a part of society now, and keeping it inefficient and slow does no one any good.
Your tirade is misguided and significantly factually inaccurate.
So would it happen if Google wasn't involved?
(The word catalyst isn’t quite right because Google took part in the reaction, but it’s the closest word to what I want that I can immediately think of.)
> You are yearning for the simple and inefficient days of yore
The simpler our systems are, the more we can understand them, and the more reliable we can make them. And more often than not, a system that's simple from top to bottom, and kept as small as possible, is efficient. Yes, I do kind of miss the days when HTTP was understandable enough that I could write my own HTTP server directly on top of a TCP socket API. TLS is a necessary evil to protect users from bad actors, but I'm not so sure about HTTP/2. In one of my Rust projects, I just switched from reqwest to ureq (yes, partly prompted by this discussion), and saved ~600K in a release build (already optimized for size). That's 600K of removed code that can't cause bugs anymore. And I know that in my particular use case, HTTP/1.1 will be good enough.
On the matter of reliability: I’d honestly expect HTTP/2 and HTTP/3 to end up more reliable than HTTP/1 (my guess is that HTTP/2 probably already is, but HTTP/3 won’t be just yet), because binary protocols require more careful implementation and generally leave much less room for bad implementation, whereas text protocols are simple enough that the average quality of implementation is much lower (because barely-skilled developers can make something that mostly works without even looking at the specs).
And to be fair, the HTTP server that I did in fact write as a teenager in the late 90s (in the MOO programming language) was firmly in that category. I'm sure my mild wishing for those days is just nostalgia.
No one as far as we know, inside or outside Google, ever figured out how to use server push to consistently speed up loading pages.
Stuff like resource media queries for instance. How the server can know if user wants dark mode or light mode CSS file?
On your particular question, there's the client hint Sec-CH-Prefers-Color-Scheme: https://web.dev/user-preference-media-features-headers/
I don't see this header being sent in Chrome 104!
Note that the server has to request that header using accept-ch.
curl --head https://sec-ch-prefers-color-scheme.glitch.me/
HTTP/2 200
date: Fri, 19 Aug 2022 18:55:43 GMT
content-type: text/html; charset=utf-8
content-length: 936
x-powered-by: Express
accept-ch: Sec-CH-Prefers-Color-Scheme
vary: Sec-CH-Prefers-Color-Scheme
critical-ch: Sec-CH-Prefers-Color-Scheme
etag: W/"3a8-iEB3drxZIB7EZYHQL534qwomDuI"Cookies? Custom header?
How exactly modern web ended up in a situation where, first time browser is displaying a single page (with maybe 3 pictures and 2 paragraphs of text), it has to download 300 resources from 12 different servers, including 2 megabytes of minified javascript?
Not sure about typical, but here is rough estimate for the rock bottom of it: "feh" image viewer on Ubuntu/X11:
$ strace -e openat -o >(wc -l) feh -F \
one.jpg two.jpg three.jpg
105That said, I would not be surprised if XFree86 was, at some point, significantly larger than contemporary web browsers, given the enormous amount of functionality that was loaded into it. Of course, modern web browsers definitely trump any old X server, so is this really relevant? I guess it depends. I get a huge sense that what people are longing for is a return to the "good ol days" when software was simple and fast, and X is a damning counter example, though it certainly doesn't mean that there's no point to be made at all, just that it is perhaps less black and white than people suggest.
I am not trying to say that feh is as complex or as slow as a web browser, only that in general, people treat the division of "native code" and "browser code" such that code running in a browser is always more bloated and slow. Somehow though, this is demonstrably not true. Looking at only very simple software with intentionally very limited scope is not going to give the whole picture. When you look at fairly complex software, the additional burden of having a browser underneath can fade away compared to algorithmic complexity issues and poorly optimized code. Your text layout and font shaping routines are probably going to struggle to compete with a browser if you have a very heavy layout to handle, and if you're doing accidentally quadratic things it's going to matter more than JIT or GC overhead.
And this time it's orders of magnitude worse.
Strawman argument.
I just want to read a damn article. Why does it need to download hundreds of resources from dozens of origins? Reading a PDF article on my desktop touches exactly one file, the PDF. Ok, maybe some dylibs from the OS related to PDF rendering. But surprise! Browsers already have everything built-in for HTML rendering! No need to download an HTML rendering engine, because it’s already there: it’s the browser!
The real waste is in the time it takes to create and destroy the connection. (hence why http/3 switched to UDP, and also why multiplexing is a thing.)
Thing is, combining js and css on the server side into 1 file pretty much negates this speed benefit. I've been building sites this way forever, and performance is great. First page takes longer, but then those files are in the cache anyway.
The actual problem is Ads. They require tracking, and of course displaying. If you're looking for waste, or indeed why a server would bother with http/3 then look no further. No ads, no problem.
Unfortunately for those sites that rely on advertising for revenue, I don't have an alternative suggestion. I get it, ads pay for lots of the Internet I "browse". I'm not a fan of pay walls and subscriptions.
So http/3 is a solution to an economic reality - and really only benefits the ad-supported Web - but for them it is important.
The wife's family living away from the main city have intermittent connection and slower speeds. We have only one submarine cable and poor infrastructure further out. So heavy, bloated sites eat up people's pre-paid internet packages quickly or have trouble loading altogether. Prepaid is around $1.25 for 500MB or $10 for 5.5GB.
I think lower bundle sizes should be a goal. Or lower bandwidth websites should be available such as a 'm.' Domain. IMO
Statements like this reminds me we live in different planets. I'd argue we should still care, just like we care about accessibility in general, but obviously it's indeed a lost cause. Anyone not on 1Gbps and 32 GB of RAM is to be relegated
The problem is that who make websites, instead of making documents, maybe built dynamically by the server and with some interactive elements in it, doesn't sent you a document but instead sends you an application that builds the document into the browser, basically turning an application that simply displays you document into a virtual machine that runs an entire graphical environment.
The fact is that most of the websites to function doesn't need a line of JavaScript, and still are downloading Mb of libraries to do what?
Most of the problems wouldn't be even present if we reason in terms of documents, and in terms of operations that you can do on these documents (GET, PUT, DELETE, POST). You find out that for most website you don't need JS!
One could argue that JS is an optimization because you don't load up again the whole page each time you navigate to a different URL. That is false: if you cache the assets that doesn't change between pages such as stylesheets and images correctly, downloading just the HTML of the page is something trivial. Look at the number of requests that a webpage that uses JS does: is that more efficient?
Mostly to polyfill around the fact that basic DOM manipulation is garbage and the default UI widgets are ugly.
^Who cares about 2 MB with 5G? That's exactly how we get into current shitty situation. Network is fast, memory is cheap so let's do whatever we want. In 2004, I only had 512MB memory on my computer, it run pretty smoothly. But now I got 64GB of memory and I run of memory now and then. I'm wondering how soon I'm going to put 1TB of RAM into my computer, not going to be too far away I reckon.
What you describe was a huge pain, most page forced us to download 15MB of data and load it in memory just to display 2 small images and some text.
A format like PDF would have been much better because we could have read enough byte until we are able to render the visible part of the document.
But instead we had to download and execute 30 javascript files.
> it has to download 300 resources from 12 different servers,
> including 2 megabytes of minified javascript?
This is "best practice" that is used widely to work around HTTP 1.1 Head of Line Blocking [1]. HTTP/2 and to a greater degree HTTP/3 (as it also alleviates TCP head of line blocking) are fixing the underlying problem making the former best practice an anti pattern (but only for those users able to use modern HTTP implementations).
[1] https://en.wikipedia.org/wiki/Head-of-line_blocking#In_HTTP
Fortunately, Reader Mode is available in a few user-friendly browsers.
If it's just a normal non-interactive website then it shouldn't have any javascript in the first place.
For example:
* If you have file A requiring file B requiring file C requiring file D you still get a chain of requests.
* Compression works a lot better the more data you throw at it, especially similar data which is usually the case for JS/CSS. SDHC was supposed to solve this, but it was never adopted by any major players besides linkedin (and google itself).
There is an argument for better congestion control. Which is funny coming from Google where they control the kernel on the server and the clients. Yes, it takes more time to deploy better congestion control if it needs kernel updates, but if it's really important to update congestion control without kernel updates, you could make interfaces for usermode congestion control.
Ads.
1) Load page through javascript-enabled browser (headless chrome, etc), and record resources accessed from the same server;
2) Save this list somewhere, where server can read it, keyed by URL;
3) When user requests same URL, push resources from the list.
The alternative (Service worker/<meta> preferch/preload tags) on other hand are much easier to handle although have one extra round trip. Because they are just text files that you need to upload to the server.
And the idea is that client would already have those files by the time browsers parses `<head>` it already has them all. Except...browser cache exists, so who cares.
The webserver could just parse the HTML and send http push for each dependency! What was the problem with doing this?
To me this seem very similar to "open document format" are storing html with all its dependency in a ZIP package. So with HTTP/2 push you just push the whole package and the client tell the server if it already have some of the files.
Well… the client knows which resources are already in its cache. The server does not. You just suggested that the server should always send resources that client almost certainly already had cached, which is wasteful for everyone involved.
> So with HTTP/2 push you just push the whole package and the client tell the server if it already have some of the files.
That doesn’t make sense. Once the files have been pushed, the bandwidth and time has already been wasted. The client doesn’t get to tell the server anything in that scenario.
If it does already have that file, client simply close the stream it doesn't need to download the file or send request to server to say it doesn't need the file.
I guess I hadn’t realized that clients could RST_STREAM on these pushes, but it doesn’t change the outcome here.
What you describe isn’t a win for anyone except a client with a cold cache, and then they start losing immediately after that. That’s why it isn’t done. That’s why HTTP/2 Push is going away.
The spec say
"The server SHOULD send PUSH_PROMISE (Section 6.6) frames prior to sending any frames that reference the promised responses. This avoids a race where clients issue requests prior to receiving any PUSH_PROMISE frames."
HTTP/2 Push is such a cool concept, but the idea of it going away also makes perfect sense to me after years of not seeing anyone find benefit.
Server push, as opposed to preload/hints, only makes sense when you know a) a client will absolutely need the data and b) you're reasonably sure the client does not have the data yet (e.g. data that is uncacheable).
Vroom [1] is a research system to accelerate page loads. It identifies dependent resources for your page and uses a combination of client hints and and server push to improve network utilization. I believe that only important, non-cacheable content use server push. See the paper for results.
To be clear, web performance is not my main field and I haven't kept up with the latest happenings. I only bring it up as evidence that push can be useful, but I can't actually say whether it's worth the complexity.
EDIT: fixed some typos.
[1] https://web.eecs.umich.edu/~harshavm/papers/vroom_sigcomm17....
One issue with the typical API formats is that all the data for each resource is shipped with the collection, which means that client caches are unaware of the 'transcluded'/'embedded' resources.
Server push, if implemented well could have allowed us to just push every collection member down the wire. Push lets you solve the Q+1 issue because all members can be generated together.
I did some work trying standardize a simple version of this: https://datatracker.ietf.org/doc/html/draft-pot-prefer-push-...
Also, at some point there were talks about a browser request header that would send the browsers' cache state as a bloom filter to the server, which would let the browser have a pretty good idea of what not to send.
When the push removal was originally announced, I wrote a bit more about this: https://evertpot.com/http-2-push-is-dead/
Anyway, I'm disappointed this happens. I get that people had trouble putting push to good use, but in my opinion this just needed more time to brew. Once Chrome announced the removal, all of this died.
Caching is also notoriously hard to get right. Apps (including web apps) usually prefer to depend on their own caching: it saves them more in development and support expenses.
The article talks about Jake Archibald enumerating some problems with PUSH. Well, Jake was also author to a mini-proposal to add Push support to fetch so developers could try out other uses for push. Seemingly ignored by chrome.
https://github.com/whatwg/fetch/issues/607
Having the browser be a minimalist, picky implementation of http protocols is hard for me to reconcile & be ok with. There's well over a half decade of neglect & plugging their ears on Chrome's side around Push, not listening to users, not delivering us low-level extensibility manifesto capable apis, and this pulling the plug is sad and sorely premature.
We are stuck forever inventing new non-http transports, over SSE, over websockets/webtransport, over long polling, becayse Chrome systematically ignored the one thing that would have made http capable of satisfying many of the desires of the old HybridBidirectional working group, & has kept the page unable to understand & recieve resources coming to it. What a blasted shame.
It may be removed from chrome, but it's still in the standard.
Sometimes specs are proved to be wrong, this is just one of those occasions.
No one uses it going forward. I'd hate to venture a guess at how many existing sites there are that use xhtml. Browsers are still expected to parse and render them properly.
What significant feature in XHTML is not supported by HTML5?
if you are only speaking about the syntax (so your statement includes XHTML5), I don't follow you neither: I don't see what's wrong with the XML version of HTML5.
`<b><p></b></p>` wouldn't stop HTML from rendering, but would stop XHTML. Plus the whole "XML parsers are very unsafe"
XML parsers are not that bad when you disable custom entities, which browsers could easily do.
It seems like the majority of developers have never really wanted to make that cost-benefit tradeoff, though. I ran tons of websites declaring an xhtml doctype through https://validator.w3.org/ back before HTML5 when xhtml was still trendy: almost all of the "xhtml" websites failed validation.
Yes, but there weren't many tools to "correctly" compose XHTML back then.
> XML parsers are not that bad when you disable custom entities, which browsers could easily do.
Yes, but it's another thing browser developers need to think of. A lot of CVEs already originate in browser. Even if it's actually safe, people who got burnt by XML, would have bad opinions about XML in mind.
Hiding errors is always a poor choice. Only if you are low paid developer not interested in making a quality product then probably you like browser's behaviour.
Some estimates say that 99% of HTML pages in the wild have at least one error in them. Yes, they errors would probably be fixed if it stopped browsers from rendering the page.
Browser plugins also had to speak valid XHTML and be able to modify documents correctly. In-line JavaScript was...funny looking. CSS also behaved differently in XHTML.
I, personally, liked XHTML behavior because errors in HTML were essentially Undefined Behavior. That resulted in different results from browser to browser (back when we had multiple browsers and not just Chrome). However, I also like Rust, so maybe it's a fetish? /s
We didn't really have good tools back then, and the way HTML was generated wasn't brilliant. Currently, I'm making a website in Yew, and it won't even compile if I don't have tags correctly placed and closed because everything inside `html!` macro gets turned into rust code and then HTML gets built. I think JSX behaves similarly?
The overall decision-making around how the web works is insane and getting more insane by the year. We have fairly trivial and absolutely universal problems unsolved for decades, while browsers get crammed full of features that aren't used by 99.9% of websites.
Worse, some problems are finally solved in such a half-assed way that it's almost worse than having no solution at all. (Input type="date", meter element, dialog element etc.)
This is not at all what I imagined the field would look like when I entered it nearly two decades ago.
Why is this surprising? Universal problems are hard to solve otherwise it wouldn't be a universal problem in the first place. Add to that large numbers of groups will have their own set of opinions on what the best solution is, and it will conflict with some ideas.
This is completely backwards. Universal problems on the web are routinely solved by everyone designing a standard website. They often have fairly standard solutions. Browser vendors routinely fail to generalize the experience of run-of-the-mill web developers. It's not about engineering. It's about misaligned incentives and operating from a bad frame of reference.
This describes most areas of applied computer science, honestly. Language design, build systems, operating systems, etc. When standards and/or widely used systems are involved, nothing is trivial. And the web is the most widely used and most standards-based system out there.
Because what I see is:
- A working element that only got half assed/ignored by one provider (Apple, but who's surprised?) which meant polyfills for years to fix it. - A niche element, there are plenty of those? - A relatively new element that solves a lot of issues with Z layer, accessibility etc and is a good basis for other components/libraries to use for their styled/enhanced modal dialogs.
Meter has a nonsensical data model and no standard way of styling it.
Dialog is a half-assed element that's useless without large amount of styling and code. For its sake they've added an additional form method, which will likely break many older JS libraries.
Mind you, we're talking about controls that have been faked or implemented on the web by developers for at least two decades. This is pitiful.
I’ll readily agree, however, that the meter element is trash, and date input an underspecified UX crapshoot.
My biggest beef with Apple’s standards engagement, however, is their intransigent and ill-considered refusal to implement customised built-in elements.
You're wrong on dialog though.
It's not half assed, it's the core functionality needed for a dialog, no more. It makes very few assumptions abouts you want your dialogs to look, or behave with closing/opening. You only have to build atop it, rather than strip it back (e.g. Like how you have to strip/reset lists to use as nav menu elements)
I've styled them and it's usually less css than equivalent bootstrap or homegrown dialogs.
I also doubt your claims that the new form method will break older js being a real problem. The method just allows js to get a standard way of how a dialog closed. I just don't see when you'd use old js that might have issues to handle that..
However, in this case it being in the HTTP/2 standard is moot, since it's just a (premature) optimization and thus its removal results in a reasonable fallback, which is simply not using that particular optimization, and also because HTTP/3 is so far along already.
Not to get too tangential, but this seems similar to fetch removing support for reponse bodies for POST/PUT requests; a login POST, for example, might return information about the user's login or the state of the server, or even a per-tab/per-page token that isn't a cookie header, but fetch simply refuses to support it (even though XMLHttpRequest still does). Fetch removing this means that additional round-trips are needed, even over a multiplexed connection, and certain app designs are simply not possible. The solution seems to be to buck the trend and just use XHR instead of fetch, especially since fetch doesn't seem to be available on older Android Chrome (possibly 5-15% marketshare even now.)
this is a salient point. if it's just an optimization and not implementing it (or removal) doesn't change behavior of sites that have adopted it, then it's benign.
Wait what? I have never heard of that, do you have a link where this removal is documented?
Seems pretty short-sighted of a decision there, since XMLHTTPReq does it just fine, and it is in the HTTP RFC's
The purpose of a standardization process isn't to stamp approval on good ideas; it's to ensure interoperability. Server Push was a plausible idea. It very much could have been a good idea. It turned out not to be, after we tried it in the real world for many years, but that's okay. And we know one thing for sure - the reason it didn't work wasn't that people were afraid to use a nonstandard X-Chrome-Server-Push extension.
HTTP/2 was what? Something no one wanted, imposed by Google? Is that too strong?
Is bottom-up maybe better in practice?
Google then used its unique position as a) massive web server and b) massive web browser to perform real-world protocol experiments that _nobody_ else could possibly do. SPDY came out of that (really cool!) work, and had some great benefits, and the working group started with the spec and worked to evolve it.
The server-push originally comes from SPDY, and as I recall it seemed an obviously useful optimization at the time. It's a bit ironic that the same company that introduced it is now saying "we never really found a use for it".
Disclaimer: I was employed by Google and on the HTTP/2 working group at the time.
here's a more cynical take:
- "only google can do these huge experiments, and we've blessed the world by sharing our discoveries, so we can have confidence that our proposals are validated with real world experience."
- "That thing we standardized and got a bunch of other people to implement? yeah, i know we said it was really useful, but we meant it seemed really useful. We actually never found a use for it."
can't have it both ways
Other vendors do this too - the fundamental conceit at play is as old as the tech sector - but that doesn’t make it any less arrogant or reprehensible behaviour.
With that understanding, the process note above from an ex-Google employee amounts to a description of wilful abuse of market power.
1. Fetching many resources simultaneously, 162 resources just for terrain data, a couple hundred more for meshes. I am currently serving with Express, so the solution here was to put Cloudflare in front of it as a reverse proxy with a short cache TTL. Cloudflare then serves them with HTTP/3. Also, requesting all of these simultaneously rather than sequentially. The header overhead isn't a problem with HTTP/3 since that uses a hash or something rather than re-sending all the same headers in each request.
2. Resource byte size. Cloudflare does Brotli but from my testing, I would need to combine terrain zones into a single binary blob for this to reduce byte size by half. (Compressing things that are a few hundred bytes achieves very little.) But combining these would mean that any change to the data of one zone would require re-compressing all zones. (Mesh compression with Draco[1] helped though.)
3. ROUNDTRIP. Especially with connection latency. This is where Server Push comes in. I actually experimented with it. But it basically only saves one roundtrip (~50-500ms depending on connection); the server establishes a connection then can push. Without server push, the server establishes a connection, then waits for the client to request resources.
The client requesting resources has a few advantages. 1) Server doesn't need to figure out what data the client needs, the client can do those calculations, and the server can simply verify (which is a lighter SQL query than discovery). 2) Client can not-request resources which it already has (in cache or storage)! 3) Resources can be cached by Cloudflare at the edge.
0: earth.suncapped.com
1: github.com/google/draco
Push also could have been useful to replace theess of non-web non-resourceful ad-hoc protocols people have endlessly kept reinventing atop WebSockets/WebTransport/SSE/Long-polling to push things like new chat messages to the browser.
The author cites Jake Archibald's struggle using Push for page loading. But Jake also was interested in expanding past this incredibly limited use case, and threw together a mini-proposal to let Fetch hear of incoming Pushed resources[2]. Chrome though largely have never acknowledged this desire, even though it's been asked for for ~7 years now.
So the web is still request & response & there's still no natural obvious way for the browser to hear of new resources that are ocurring. Chrome didnt listen to developers, never let us actually use the feature, and now they're killing it, and we're stuck where we were two decades ago, scabling to figuring out what to do to get some bidirectionalism beyond request-response.
The Push API <https://w3c.github.io/push-api/> is a completely different thing with absolutely nothing in common with HTTP/2 PUSH frames (Server Push), just like Server Push is nothing to do with Server-Sent Events. PUSH frames would be unsuitable for the Push API, which is all about not having to keep a connection alive.
(The rest of your comment is still valid, though I reckon you overstate the practical usefulness/superiority of Server Push somewhat—sure, the ability to push multiple streams instead of just one is useful in some cases, helping avoid head-of-line blocking or subprotocol complexity, but in practice I suggest that most scenarios can’t actually use that power at all.)
https://datatracker.ietf.org/doc/html/draft-ietf-webpush-pro...
You've listed some fine advantages of Push frames, but the one most near & dear to me is that it is supported by HTTP itself & delivers http resources. This is an incomparable advantage versus everything else: slotting nicely into the existing ecosystem.
With QUIC based semi-connectionless HTTP3, the advantagea would only have been further accelerated, no longer even needing a TCP connection to be maintained.
I see now that I misunderstood what you were speaking of by “under-the-hood”. I was thinking about the developer-facing parts of the Push API, but you actually meant the bit in the browser’s control, opaque to the developer. I retract my quibble.
Currently it seems like the best option is to use Transfer-Encoding: chunked and make sure you flush out an HTML header that includes the preload directives before you spend any time rendering the web page. This is a pain - especially if something in the rendering fails and you now have to figure out how to deliver...something to the client. It also limits other headers significantly - e.g. cookies.
[1] https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/103
“Access forbidden, here have this css file instead”
Or did you mean HTTP Status 103?
The other is flow control. A server push doesn't automatically send the entire object. It opens a new stream and fills the window, but the client must actively read / ack the stream for the remainder to be sent. To do otherwise would allow the server to de-facto violate the client's stated flow control settings and potentially DoS their network link.
[le: curious about the downvotes (-3), for anyone willing to shed some light]
(le2: turns out I’m using Server Side Events and not HTTP2 server push; sry for the noise)
Over that database I have a tiny Koa server that checks if URL is still active, processes image in memory and serves it through HTTP2 over to a Preact app that handles displaying them.
I do this so I can share this with some people, and allow them to share some stuff without exposing myself to liability for hosting.
I don't know what country you live in, but here where I live (in the US) you definitely aren't avoiding any legal definition of hosting by only relaying.
Chrome using their browser-adoption super majority to force standards change. This is monopolistic behavior I'd say, and I'd be glad to see it stop.
location ~ ^(?<canonical>.*)\.html$ {
access_log off;
log_not_found off;
http2_push $canonical;
return 301 $canonical;
}Mozilla has it as "worth prototyping" https://mozilla.github.io/standards-positions/#http-early-hi... and their tracker entry is https://bugzilla.mozilla.org/show_bug.cgi?id=1407355
Folk have been using this technique for a decade or more
<script> window.initialData = { isLoggedIn: true, email: 'example@example.com', todos: [ ... ] } </script>
I even wrote a web server with bundled framework (as an academic exercise) whose whole purpose was to work like this. It was basically made for delivering any given bundles of assets over a WebSocket and had some cool features like the ability to auto-encode, auto-compress, or translate from one file type to another (say, turning a PNG into a JPEG or minifiying JS/CSS) as a simple matter of modifying the configuration.
https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/103
I have a dev http/2 server that is serving my app locally, amounting to 271 module dependencies. It takes about 400-500ms to load everything and startup the app. The implementation is trivial and without errors, every dependency can locate its assets because it sits at its real path, sourcemaps etc.
Switching to Early hints/Link: it becomes 4-5s and even with all of the modules cached, it doesn't get less than 2-3s. So this could be an implementation difficulty and might be improved, but it is still a non-trivial overhead.
Now the only viable solution becomes bundling, even with esbuild the improvement over http/2 push is marginal. But now there is an extra build step that before was handled at the HTTP layer by "push". The files are bundled to a single file, so they no longer can access their assets relatively to their path, since they have changed paths. Workers etc. have the same problem, import.meta.url no longer works and so they can't be located. Not without various steps of transformations and assets handling, and there'll always be edge cases where those are going to fail. Certainly not composable across domains/projects since by bundling they become hardwired to their environment.
Push doesn't have these problems. So, it's a step backwards IMO to remove it. Without "push", the only viable solution becomes to use 3rd party bundling tools for any non-trivial work that exceeds a handful of dependencies, where with "push" you could deploy the exact structure of the code as it was. Bundling makes source code and the web less open and less accessible and with this change there is no other solution. Early hints are fine when dependencies are less than a dozen, but it becomes much worse as they grow, leaving you with no choice than build steps/bundle steps, instead of simply uploading the directory of your source code to the http/2 push server leaving the structure intact.
My home built IDS/XDN was struggling against that.
And the rest of the XDN industry probably thank you too.
Server Push just deals with eagerly loading assets like CSS, JS, and images.
It is the biggest tech retrograde since MS started putting UUIDs in to their Urls. Which they largely stopped except for sharepoint documents.
Also, I think you may be mistaken about being "(kinda) server-push" - Cache API is entirely client-driven: the server can't push items into that cache; the client (usually a service worker) must choose to do so. I don't know what you mean when you say it's like server push.
[0]: https://debuggerdotbreak.judahgabriel.com/2022/07/01/offline...
Remember, "client" (assuming user didn't disable javascript) is a dumb machine that executes whatever (code downloaded from) server tells it to, within some (pretty generous) limits. Imagine index HTML containing this:
<script>
const cache = await caches.open('push');
cache.put('/resource.json',
new Response('{"foo": "bar"}'));
cache.put('/resource.gif',
new Response(atob('R0lGODlh...'));
</script>
That, of course, assumes that rest of code would use cache.match() instead of fetch API or XHR. Or, more realistically, a wrapper that tries both.My answer is no, of course not, because Cache API is unrelated to HTTP/2 push. It's useful for storing resources regardless of whether they're HTTP/2 push'd from the server or fetched from the client. Indeed, the primary use of Cache API is storing resources fetched from a client's service worker.
The TCP head-of-line problem makes HTTP/2 a solution ONLY for people that abuse the bandwidth in the first place (read big centralized coorporations that have large bills of wasted eletricity) making it a non-solution across the board for the distributed (hosting HTTP from home) humanity.
The reason for "eternal growth" mindset is job security:
"What are all these people going to do now that we have the final HTTP/1.1 working perfectly across the globe on every machine?" Depreceate and "improve"...
In my mind the second version (not always named 2) is always the final version, see half-life and starcraft for other stories that tell you a similar progression: you make 1.0 as well as you could and then take a pause and realize you need some final additions so 1.1 completes the product/protocol. (both HL and SC where rewritten in a large manner after they where "done").
2.0 is often a waste of resources, see HL2+ and Starcraft 2, where the electricity prices are going now and for eternity you wont be able to play them anyway!
Complexity has a price, HTTP/1.1 is simple!
But it's obviously much easier to criticize if you don't actually dive deeper than the name of things.