25 ms·
> The webserver could just parse the HTML and send http push for each dependency! What was the problem with doing this? Well… the client knows which resources
by coder543 4y ago
> The webserver could just parse the HTML and send http push for each dependency! What was the problem with doing this?
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.
- 0x457 4y agoI guess the client could tell server that "I already have that file in cache", but it's still weird, might require another round-trip (server asking if client needs this file).
- skyde 4y agoa push is an HTTP2 stream. the stream header contain everything the client need to know if it already have that file. 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.
- coder543 4y agoEven then, the average case would still be worse because the server would be sending all these unnecessary stream headers and forcing the client to send so many unnecessary RST_STREAM frames back. Each PUSH_PROMISE is supposed to contain the full set of headers for each resource. 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.
- Matthias247 4y agoEven if a client does a RST_STREAM, the origin server might already have done a lot of additional work (e.g. request the pushed file from an upstream if it's a proxy/CDN), and probably stuffed min(TCP_SEND_BUFFER_SIZE, STREAM_FLOW_CONTRO_WINDOW) of data into the stream. Which then also means all of that work might get billed if the server is a managed service. It's really quite some waste of resources compared to the client sending an additional request (which might even be a conditional request).
- coder543 4y agoYeah, and unless I’m wrong, this also means the TTFB could be significantly higher, since I think the PUSH_PROMISE frames need to come before the main content. Doing that at least requires gathering up the information on those objects, which takes time.
- skyde 4y agoyou are 100% right :-( 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."
- Matthias247 4y agoeven if a server implements that behavior, it could however just send the PUSH_PROMISE frame (containing HTTP headers) but doesn't have to send the associated data frames yet. The frames associated with the original response could follow earlier.
- skyde 4y agoyeah depend if you care more about saving bandwidth or reducing the time it take to display the page.
- coder543 4y ago
- rndgermandude 4y agoThe http/2 stream is multiplexed over a regular tcp stream. At least some push HEADERS and data was most likely already send over the tcp stream, and is most likely already a few hops away from the actual server. By the time the server actually gets the first http/2 RST_STREAM(s) a lot of data from multiple useless pushes could be inflight already. At this point you cannot just close the http/2 stream to avoid data being send. You can only either RST the entire tcp stream and kill all multiplexed http/2 flowing over it (avoiding some data transfer), or accept the data that arrives on your closed http/2 streams and send it in the direction of /dev/null. 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).