47 ms·
Removing HTTP/2 Server Push from Chrome
- rektide 4y agoAs usual from Chrome, 100% ignores the fact that developers have wanted to use fetch to be able to reactively hear of resources coming in, & chrome has (largely) ignored these pleas. The post focuses only around the most boring & basic capability of webpage loading, since that was the only capability developers ever got. 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 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.
- pull_my_finger 4y ago> The web needs to be able to try things, and discard them when they are not used. 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.
- nousermane 4y agoAre they going to kill Cache API [0] as well? because if not, one can still (kinda) "server-push" stuff through that. [0] https://developer.mozilla.org/en-US/docs/Web/API/Cache https://developer.mozilla.org/en-US/docs/Web/API/Cache
- judah 4y agoCertainly not. Cache API is a useful API that can enable faster web apps by skipping network calls altogether. It also enables offline-capable web apps. I regularly use this API to speed up my web apps -- both personal and professional. I recently wrote about using Cache API to make a web app work entirely offline: [0]. 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-pwas-my-adventure-beyond-the-basics/ https://debuggerdotbreak.judahgabriel.com/2022/07/01/offline...
- nousermane 4y agoCache API being "useful" and "entirely client-driven" - both great points, but how is does it contradict my statement about same API being usable for server-push (i.e. force-feeding some objects to client it didn't ask for), may I ask? 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.
- judah 4y agoI don't deny that Cache API was usable from HTTP/2 push. I'm responding to your question asking whether Chrome will obsolete the Cache API because it was usable from HTTP/2 server push. 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.
- ThalesX 4y agoHuh, I just moved my NSFW scraper to serve me content through HTTP2 server push. Guess it’s back to the drawing board. [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)
- coolspot 4y agoCan you elaborate, for my friend, please.
- ThalesX 4y agoNot all that complicated, I have some places on the interwebz where my kind of NSFW content is posted so I scrape those and maintain an SQLite database of direct urls. 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.
- detaro 4y agoI'm fairly certain you are confusing Server Push with something else, because as far as I can tell Server Push is not useful for doing what you describe.
- jefftk 4y ago2020-11 announcement with technical details on why they're removing it: https://groups.google.com/a/chromium.org/g/blink-dev/c/K3rYLvmQUBY/m/vOWBKZGoAQAJ https://groups.google.com/a/chromium.org/g/blink-dev/c/K3rYL... 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.
- msoad 4y agoPush is a bad design. The client should manage the resources on the client not the server. Stuff like resource media queries for instance. How the server can know if user wants dark mode or light mode CSS file?
- jefftk 4y agoI agree on removing it, since it turned out not to work well despite lots of people trying. On your particular question, there's the client hint Sec-CH-Prefers-Color-Scheme: https://web.dev/user-preference-media-features-headers/ https://web.dev/user-preference-media-features-headers/
- msoad 4y ago> The Sec-CH-Prefers-Color-Scheme client hint header is supported on Chromium 93. Other vendors' feedback, namely WebKit's and Mozilla's, is pending. I don't see this header being sent in Chrome 104!
- panopticon 4y agoWorks on Chrome 104 for me: https://sec-ch-prefers-color-scheme.glitch.me/ https://sec-ch-prefers-color-scheme.glitch.me/ Note that the server has to request that header using accept-ch.
- msoad 4y agocurl --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"
- sidcool 4y agoIs Websockets a viable option to HTTP2 server push?
- detaro 4y agoWebsockets serve entirely different purposes.
- luhn 4y agoYou might be confusing Server Push with Server-Sent Events. https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events https://developer.mozilla.org/en-US/docs/Web/API/Server-sent... Server Push just deals with eagerly loading assets like CSS, JS, and images.
- unlog 4y agoWhat we need is somehow the ability to serve the html/js and json at the same time without having to wait for the client to get the html and then do the fetch request for that json. This will save a full round trip for loading content while keeping things simple.
- yread 4y agoI just generate the json when loading the page and embed it as script with a nonce. Of couse I lose the caching of the "static" page but it's worth it.
- GordonS 4y agoHmm, that's an interesting idea - perhaps the browser first downloads some kind of "manifest" file, which lists the required URIs, then the browser can request them all at once?
- jefftk 4y agoI think you're asking for https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/103 https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/103 Mozilla has it as "worth prototyping" https://mozilla.github.io/standards-positions/#http-early-hints https://mozilla.github.io/standards-positions/#http-early-hi... and their tracker entry is https://bugzilla.mozilla.org/show_bug.cgi?id=1407355 https://bugzilla.mozilla.org/show_bug.cgi?id=1407355
- toast0 4y agoIf you're going to serve all the js all the time, put it inline.
- EarthLaunch 4y agoHTTP/2 Server Push being impractical matches my experience on getting my game client[0] to load quickly (2.5 - 3.5 seconds via Starlink, for cold - warm cache). What slowed it down: 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
- ryantownsend 4y agoYou've got a fairly heafty JS file on the critical rendering path (350kb), so one option to help your roundtrips 3 is to preload the other files it uses so it's not dependent on the JS download and executing before they are discovered. See: https://web.dev/preload-critical-assets/ https://web.dev/preload-critical-assets/
- EarthLaunch 4y agoThanks! That JS file is the whole minified application. The application is what knows what needs to be loaded - so I would have to move that logic out into the page. It would help but I am not sure it's worth the cost of maintaining that extra logic, in this case (being indie).
- bullen 4y agoWe already have Server Sent Events over HTTP/1.1 so yes this was completely unneccessary. 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!
- detaro 4y agoServer Sent Events and Server Push don't really have anything to do with each other... (SSE is still a thing with HTTP2/3 too)
- deleted 4y ago[deleted]
- rubenv 4y agoServer Sent Events and H2 Server Push serve completely different purposes, one is about application messages, the other about loading resources. But it's obviously much easier to criticize if you don't actually dive deeper than the name of things.
- chrsig 4y agothis really strikes me as evidence that something is wrong with the http standardization process. we should know if something's a good idea before immortalizing it in a standard. It may be removed from chrome, but it's still in the standard.
- nousermane 4y agoWell, IETF can always publish an HTTP/2.1 with that removed, no?
- chrsig 4y agoan HTTP/2.1 doesn't stop HTTP/2 from existing, it just creates another standard.
- samwillis 4y agoHTML5 doesn’t stop XHTML from existing, however it’s collectively considered a bad idea and no one uses it. Sometimes specs are proved to be wrong, this is just one of those occasions.
- chrsig 4y ago> however it’s collectively considered a bad idea and no one uses it 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.
- samwillis 4y agoTrue, although in this case no one is using HTTP/2 Push, so removing it is no harm and only makes it easer to maintain browsers.
- jraph 4y agoWhat's wrong with XHTML 1.0 or 1.1? (assuming you are speaking about this) 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.
- NightMKoder 4y agoThey mention this in the doc, but it seems like the future solution to preloading resources will involve HTTP Status 403 [1]. That seems like a great alternative to server push. 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 https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/103
- orangepanda 4y ago> solution to preloading resources will involve HTTP Status 403 “Access forbidden, here have this css file instead” Or did you mean HTTP Status 103?
- NightMKoder 4y agoLol yes of course I meant 103. Though I’m ready for an http status code that’s like that: “I can’t give you what you want, but here’s something you didn’t even ask for instead.”
- chrisshroba 4y agoIn case anyone is confused, I believe the parent poster means 103, not 403.
- a-dub 4y agoit was a cool idea, but i don't remember even seeing it implemented in spdy which is where i believe it came from.
- rektide 4y agoAs I commented yesterday[1], accelerating page loading was only one use case for http Push frames. Alas it's the only ude case Chrome ever acknowledged or cared about or have ever seemingly recognized (in spite of it under-the-hood powering Push API). 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. [1] https://news.ycombinator.com/item?id=32514159 https://news.ycombinator.com/item?id=32514159 [2] https://github.com/whatwg/fetch/issues/607 https://github.com/whatwg/fetch/issues/607
- chrismorgan 4y ago> in spite of it under-the-hood powering Push API The Push API <https://w3c.github.io/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.)
- rektide 4y agoThe only standardized implementation of Push API is Web Push Protocol, which uses HTTP Push frames to push new message resources. https://datatracker.ietf.org/doc/html/draft-ietf-webpush-protocol 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.
- hackbinary 4y agoIt would be great if Google stopped making nasty Urls with the nasty "Scroll To Text Fragment" feature. It is the biggest tech retrograde since MS started putting UUIDs in to their Urls. Which they largely stopped except for sharepoint documents.
- treve 4y agoThe reason I'm a little disappointing about this, is because I was really hoping for a future where we improve sending collections of items from APIs. 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-01 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/ 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.
- nine_k 4y agoI'm afraid per-item responses are not very realistic, even with HTTP/2 and efficient message formats. The items then begin to be comparable, or smaller, than the client identity token sent with each request. Its size is limited by cryptography. 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.
- lsaferite 4y agoFunny thing is that I was just looking into how this software could work with APIs and now it seems like it's dead in the water if the support is removed from the browser. Sure, it's a progressive enhancement and you wouldn't break anything, but you lose all the benefit as far as I can tell and you _are_ adding an extra layer. https://github.com/dunglas/vulcain https://github.com/dunglas/vulcain
- jksmith 4y agoThis is forcing a solution to fit the problem.
- stagas 4y agoI posted this at the Google group, though it is pending approval. So this is a shorter version of it from memory: 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.
- jefftk 4y agoYou might be interested in subresource bundles? Shipping in Chrome 104 https://chromestatus.com/feature/5710618575241216 https://chromestatus.com/feature/5710618575241216
- pornel 4y agoWhat really killed it was an awful implementation. It did not simply push things into browser’s cache. Instead, pushed items were held in some kind of temporary purgatory, and would be discarded if browser didn’t immediately have a need to request the pushed resource.
- jgraettinger1 4y agoIIRC there were two reasons for this. One was an information-leak concern whose details I don't fully remember. 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.
- y42 4y agoWhy is everyone so mad about this feature? Maybe I do not understand Server Push in http2, but isn't it useful to e.g. send a rendered picture to the client instead of the client polling the server every 5 ms until the image is ready? What about chat applications?
- tannhaeuser 4y agoSo first Google (Chrome team) foobar'd HTTP (and HTML and CSS and ...) into overengineered crap to replace TCP with vague promises of pushed resources and multiplexing only necessary to handle absurdly bloated CSS, images, and fonts there for CDNs by Google et al to sensor your traffic and visit data in the first place, then they admitted server push, as the other touted advantage, being not well thought out after all. The effect being to derail most F/OSS HTTP libs, web servers, and TCP/IP stacks due to sheer complexity and conflicting goals. Wish we'd call Google's destructive efforts towards the web as what they are.
- omginternets 4y agoNit: I think you mean FUBAR. :)
- jonhohle 4y agoOn a technology forum, `foobar` seems like an appropriate replacement.
- gfodor 4y agoHey at least they’re killing it. Which would be, under the frame you’ve laid out here, a kind of progress?
- yoro46 4y ago>The effect being to derail most F/OSS HTTP libs, web servers, and TCP/IP stacks due to sheer complexity and conflicting goals. 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.
- 4y ago
- vbernat 4y agoIt was quite useful to speedup redirects: location ~ ^(?<canonical>.*)\.html$ { access_log off; log_not_found off; http2_push $canonical; return 301 $canonical; }
- egberts1 4y agoTHANK YOU for removing server push HTTP/2. My home built IDS/XDN was struggling against that. And the rest of the XDN industry probably thank you too.