Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for HTTP/2 with server push #238

Open
doug-wade opened this issue May 31, 2016 · 9 comments
Open

Add support for HTTP/2 with server push #238

doug-wade opened this issue May 31, 2016 · 9 comments
Labels
enhancement New functionality.

Comments

@doug-wade
Copy link
Collaborator

One of the most powerful things about react-server is that the server-side knows, in a structured way, about all of the associated resources for a page (JS, CSS, JSON XHR) and could push them pro-actively. Not only would this theoretically be faster than the current code, it would also obviate the need for the ReactServerAgent cache, which would simplify the logic a lot in the HTTP/2 case.

Migrated from #50

@gigabo gigabo added the enhancement New functionality. label Jun 1, 2016
@aickin
Copy link
Contributor

aickin commented Jun 3, 2016

FYI for anyone thinking of working on this issue: I know that @roblg poked at it and built a working prototype. Also, the biggest problem he ran into was that Express is not compatible with node's http2 library (for extremely byzantine reasons). He had to migrate from Express to connect to get it to work.

cc @withinboredom

@gigabo
Copy link
Contributor

gigabo commented Jun 3, 2016

From @withinboredom in #259:

I lately implemented a wordpress plugin for my workplace that turns this on. This is actually simpler than you'd think. I'm going to take a look under the hood of react-server and document the work that needs to be done and then we can figure out what to do about it.

Thanks @withinboredom!

@kcjonson
Copy link

kcjonson commented Jun 9, 2016

I was able to use the spdy module to get an HTTP2 example together with express, code here: https://github.com/kcjonson/http2-boilerplate/tree/master

Edit: link to spdy: https://www.npmjs.com/package/spdy

@karlhorky
Copy link
Contributor

@withinboredom Any news on this?

@doug-wade
Copy link
Collaborator Author

I've been trying to keep my eye on this. Work has been progressing pretty well on http2 in node core -- it looks like they're targeting having it available behind an experimental flag in node 8. I've been periodically building and tinkering with the in-progress http2 branch, and I believe that barring anyone else having implemented this, I should have a PR open sometime in April.

@karlhorky
Copy link
Contributor

@doug-wade great, thanks for the update!

@aickin
Copy link
Contributor

aickin commented Jan 6, 2017

FWIW, my thinking on this has changed a bit since I filed it in #50 after I went to Velocity this past fall and started poking at server push for a few weeks.

One of the talks I saw at Velocity (lightly) suggested that server push is generally probably a bad idea at this point. It turns out that, at least as of October or so, no browsers implement client cancellation of push streams when a resource is already in cache. So if you always blindly push all your affiliated static resources, you will lose the entire benefit of the browser cache on repeat visit, at least as far as bandwidth is concerned.

Additionally, the speaker I saw suggested that even if browsers did support cancelling push streams, it wouldn't result in a lot of perf saving because in many cases the server would end up sending down a lot of the pushed resource before getting the cancellation. (I vaguely remember the speaker saying something about a situation where the server can easily get most of the pushed resources into the network buffers before the stream cancellation comes back from the client, but don't quote me on that.)

There is a rough plan to fix this situation but it's pretty early days. There's a draft spec for Cache Digests, which would allow browsers to send a compressed digest of all the server's URLs in the browser cache. The server can check what's in the client's cache and use that to decide what to push and what not to push. Due to some clever math, the digest is quite compact over the wire, although that compactness comes at a price: the digest is probabilistic and allows for some chance of false positives. In case of a false positive, the server incorrectly will believe that the client has the resource in cache, but that turns out to be fine; it just means the browser will request the resource as usual.

I believe that no current browsers support cache digests, but I might be wrong. Until they do, though, I feel like http/2 push is probably not a great feature for react-server. There are some implementations, like the h2o server, that have hacked together cache digests implemented in HTTP cookies, but that feels pretty brittle to me and not worth the effort if real cache digest support is on its way eventually. YMMV, of course.

There's a good, long article about some of the tradeoffs here: http://calendar.perfplanet.com/2016/cache-digests-http2-server-push/

@karlhorky
Copy link
Contributor

karlhorky commented Jan 6, 2017

Wow, didn't know about the downsides, good points. This is something that should be communicated loud and clear in the infrastructure / performance communities.

Edit: Doing my part: https://twitter.com/karlhorky/status/817515226564329473

@dfabulich
Copy link
Contributor

That blog post mentions that Service Workers can polyfill HTTP/2 cache digests. On first load, the H2 server pushes everything. On second load, the browser hits the Service Worker, which can compute the cache digest itself and add it as a custom header to the request. The server can use the cache header to decide what to push and what not to push in the subsequent response.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New functionality.
Projects
None yet
Development

No branches or pull requests

6 participants