
Nginx HTTP/2 server push support - x25519
https://hg.nginx.org/nginx/rev/641306096f5b
======
jbergstroem
I've recently spent more time using H2O over nginx, mainly because of its more
complete support of HTTP 2 (push, cache-aware push, ..) but also out of the
box support for brotli compression and mruby (think lua landscape for nginx).
Even though nginx made it easier to build and ship third party modules
separately, I feel like the module community (as well as distro
maintainers/packagers) haven't followed suit. There's obviously pre-baked
packages like openresty which has lua world, but then there's no brotli.

~~~
vbtechguy
been using ngx_brotli with my Centmin Mod Nginx stack for what seems like
years now [https://community.centminmod.com/threads/how-to-use-
brotli-c...](https://community.centminmod.com/threads/how-to-use-brotli-
compression-for-centmin-mod-nginx-web-servers.10688/) :)

~~~
jbergstroem
The upstream repo from google hasn't been updated in over a year; issues are
being opened questioning maintainership. It additionally breaks against more
recent version combos of nginx/brotli.

There's an active fork here (which I also use on my remaining nginx instances)
[https://github.com/eustas/ngx_brotli](https://github.com/eustas/ngx_brotli)

~~~
vbtechguy
yup i am using eustas fork for ngx_brotli works well :)

------
linsomniac
Just a heads up, we tried to enable H2 with haproxy 1.8.3 last week and had to
roll it back because of a Firefox bug. I believe it's this one, which doesn't
seem to be getting much attention:
[https://bugzilla.mozilla.org/show_bug.cgi?id=1427256](https://bugzilla.mozilla.org/show_bug.cgi?id=1427256)

~~~
x25519
That bug has been fixed in 1.8.3 ([https://www.mail-
archive.com/haproxy@formilux.org/msg28501.h...](https://www.mail-
archive.com/haproxy@formilux.org/msg28501.html))

Source:
[https://bugzilla.mozilla.org/show_bug.cgi?id=1427256#c7](https://bugzilla.mozilla.org/show_bug.cgi?id=1427256#c7)

~~~
ghusbands
Glad to see the bug is now updated/fixed, but the person you're replying to
said they were already using 1.8.3. I guess you're saying their issues were
caused by a different bug.

------
TheAceOfHearts
Please correct me if I'm wrong in anything I say here. I haven't had any real-
world deployment experiences with HTTP 2.0.

Every time I've tried looking into it, I've found it underwhelming.
Infrastructure support and tooling is still heavily lacking as far as I can
tell. To really take advantage of server push it seems like you'd need to have
really good build tools available.

Don't you risk sending useless data with server push? How do you handle cached
resources? Just because a view depends on some resources, it doesn't mean you
always need to send em down to the client.

Having server push doesn't always mean you should avoid bundling and minifying
resources. Won't a gzipped bundle typically produce a smaller payload?

Maybe I'm totally wrong or I've misunderstood something, but the general
impression I've gotten is that the benefits of server push are a bit
overstated. Does anyone have links to resources which discusses these issues
in depth?

~~~
dalore
Good questions. I was looking at H2O and they solve this using what they call
http-casper:
[https://h2o.examp1e.net/configure/http2_directives.html#http...](https://h2o.examp1e.net/configure/http2_directives.html#http2-casper)

> When enabled, H2O maintains a fingerprint of the web browser cache, and
> cancels server-push suggested by the handlers if the client is known to be
> in possession of the content. The fingerprint is stored in a cookie...

That sounds interesting solution.

Actually it looks like this tool along with nginx pagespeed would work well
and require no changing in build tools.

Nginx pagespeed supports parsing and optimizing the html (and linked
resources), including inserting prelink headers. Which will now get pushed. It
requires no change in build process.

> Won't a gzipped bundle typically produce a smaller payload?

With http2 it's better to unbundle these days as the best reason for bundling
was to not create new tcp connections which require ramp up time to be useful.
Now with http2 the same tcp connection is used but multiplexed. So the main
reason for bundling goes away. As to it producing smaller payloads, it might
be the case but not that much smaller that it's worth it since it's the same
tcp connection. Better to have it in unbundled then it gets parsed and
processed in chunked streams of files. The client is able to use and process
the files as they come in without having to load the whole bundle and process
at once. Making the site a bit more responsive.

~~~
josephscott
That is the theory. The real world however can be very messy. More than two
years ago Khan Academy measured how this would work for them -
[http://engineering.khanacademy.org/posts/js-packaging-
http2....](http://engineering.khanacademy.org/posts/js-packaging-http2.htm) \-
here was their summary:

> The reality is not so rosy. Due to degraded compression performance, the
> size of the data download with individual source files ends up being higher
> than with packages, despite having achieved 'no wasted bytes'. Likewise, the
> promised download efficiency has yet to show up in the wild, at least for
> us. It seems that, for the moment at least, JavaScript packaging is here to
> stay.

My personal experience has been you have to confirm the theory of how HTTP/2
related changes will perform with actual measurements. I've seen some pages
get faster in HTTP/2 by no longer bundling, and in other cases seen then
become slower. So far the only way to know for sure is to measure the result.

~~~
Ajedi32
> Due to degraded compression performance

Are there any efforts underway to fix that? Seems like you could solve that
problem by sharing the compression dictionary between documents transmitted
over the same connection.

~~~
SahAssar
There are (SDCH), but they are basically abandoned and are close to being
unshipped in chrome (which is the only browser that supported them):
[https://groups.google.com/a/chromium.org/forum/#!topic/blink...](https://groups.google.com/a/chromium.org/forum/#!topic/blink-
dev/nQl0ORHy7sw)

I looked into using SDCH for topojson, since it seemed like a match made in
heaven (a lot of repeated bytes in many files that are usually static), but
since it never took off in usage it is being removed. The only major site that
used it is linkedin.

EDIT: the continuation of this is basically what brotli is. Gather a
dictionary of the most common byte-sequences on the internet, pre-ship that in
every client and use that as the shared dictionary. But it will never be as
good for specific use-cases.

------
poyu
Here's a really nice write up on server push optimization from the Chrome
team.

Rules of Thumb for HTTP/2 Push

[https://docs.google.com/document/d/1K0NykTXBbbbTlv60t5MyJvXj...](https://docs.google.com/document/d/1K0NykTXBbbbTlv60t5MyJvXjqKGsCVNYHyLEXIxYMv0/edit)

------
carlosvega
Interesting video about HTTP 2.

[https://www.youtube.com/watch?v=0yzJAKknE_k](https://www.youtube.com/watch?v=0yzJAKknE_k)

~~~
smartbit
Excellent talk & speaker, slides
[https://www.slideshare.net/Fastly/http2-what-no-one-is-
telli...](https://www.slideshare.net/Fastly/http2-what-no-one-is-telling-you)

Follow up talk _Revisiting HTTP /2_ given Jan 31, 2018
[https://www.youtube.com/watch?v=wR1gF5Lhcq0](https://www.youtube.com/watch?v=wR1gF5Lhcq0)
& slides [https://www.slideshare.net/Fastly/revisiting-
http2-87148462](https://www.slideshare.net/Fastly/revisiting-http2-87148462)

------
x25519
They did a static analysis and fixed a null pointer dereference here:
[https://hg.nginx.org/nginx/rev/8b0553239592](https://hg.nginx.org/nginx/rev/8b0553239592)

~~~
jchb
They might want to consider using clang nullability annotations (_Nullable
etc) when compiling on clang. Can use a macro so it becomes a noop when the
compiler does not support it. The static analyser would then get a lot of more
information to work with, and it also serves as a kind of documentation.

------
pgjones
Server push in Python
[https://pgjones.gitlab.io/quart/serving_http2.html#server-
pu...](https://pgjones.gitlab.io/quart/serving_http2.html#server-push-or-push-
promises)

(I am the Quart author, thought this would be interesting and relevant).

~~~
drcongo
As someone who loves Flask and finds Django infuriating, I've been keeping an
eye on Quart, it looks really interesting.

------
Mojah
For those interested, I wrote a lengthy blogpost about HTTP/2 a few years ago,
detailing the architectural/infrastructure changes needed to support it for
your endusers: [https://ma.ttias.be/architecting-websites-
http2-era/](https://ma.ttias.be/architecting-websites-http2-era/)

------
ubercow
How are you going to signal nginx what to push?

Are you going to be able to push stuff from your application if using Nginx as
a proxy? For example, a dynamic view that includes a css file hosted by nginx.

~~~
rictic
Quoting the OP:

> Also, preload links from the Link response headers, as described in
> [https://www.w3.org/TR/preload/#server-push-
> http-2](https://www.w3.org/TR/preload/#server-push-http-2), can be pushed,
> if enabled with the "http2_push_preload" directive.

So you send down some headers in your response which tells the proxy server
resources it should push. Pretty elegant, and fails gracefully. I believe this
is the same mechanism as other http2 servers.

------
spiderfarmer
How is browser support for server push nowadays? Back in March Jake Archibald
noticed a lot of oddities in mainly Safari and Edge:
[https://jakearchibald.com/2017/h2-push-tougher-than-i-
though...](https://jakearchibald.com/2017/h2-push-tougher-than-i-thought/)

------
mozumder
This doesn't seem to have a level of "cache-aware server push" that h2o
(awesome http/2 server) has. Is there any info on how Nginx deals with cached
server push?

~~~
vbtechguy
been testing Nginx 1.13.9 via master branch with my Centmin Mod Nginx stack
and HTTP/2 push testing by setting up cache aware HTTP/2 push via conditional
preload link resource hints headers which only show up when a cookie is absent
[https://community.centminmod.com/threads/hurray-
http-2-serve...](https://community.centminmod.com/threads/hurray-
http-2-server-push-for-nginx.11910/page-2#post-59423)

works so far but still waiting on bug fix
[https://trac.nginx.org/nginx/ticket/1478](https://trac.nginx.org/nginx/ticket/1478)
as Nginx has pushed back 1.13.9 release until next week
[https://twitter.com/nginx/status/963442197436678144](https://twitter.com/nginx/status/963442197436678144)

------
niftich
As more software is adding support for HTTP/2 server push, I hope they'll
start supporting a higher-level, implementation-agnostic, declarative way of
specifying resources to push, which operates at a layer higher than server
config directives.

Google has a dead-simple JSON format [1] for this from 2015.

[1] [https://github.com/GoogleChromeLabs/http2-push-
manifest](https://github.com/GoogleChromeLabs/http2-push-manifest)

~~~
SahAssar
Most servers just read the preload headers from the backend and use that as a
push. That won't work with "HTTP 103 Early Hints" (Since it needs to know what
to push before the backend responds), but for now a preload header is a good
compromise between ease-of-use and good-enough.

------
alwillis
Glad push support is finally about to ship.

------
seanwilson
Are there any good general guidelines on when you should use HTTP2 push?

Edit: Oops, I missed out "push" at the end.

~~~
crishoj
I would suggest using HTTP/2 whenever possible. Features like connection
multiplexing and pipelining alone are huge benefits.

~~~
smartbit
Research by Homaan Behesti of Fastly (above at
[https://news.ycombinator.com/item?id=16365413#16365605](https://news.ycombinator.com/item?id=16365413#16365605))
suggest that _you_ test h2 with _your site_ and see how h2 compares to h1.

------
therealmarv
Can somebody explain in simple words what HTTP/2 push means? Example?

~~~
moviuro
Client: may I get /index.html please?

Server: sure, here's index.html, theme.css, and jquery.js.

Client: hey wait! I didn't ask for... oh, nvm, good call. Now I can display
all this without asking you for anything else.

EDIT: See this:
[https://youtu.be/0yzJAKknE_k?t=30m52s](https://youtu.be/0yzJAKknE_k?t=30m52s)
for more details

~~~
abricot
And add-track.js, flash-banner.gif?

~~~
janfoeh
This is just fancy cache-prewarming. The client still decides what resources
to request, but those it wants to fetch are available locally at request time.

("just" as a qualifier for nefariousness, not usefulness)

------
nodesocket
Awesome. Is this going to make it into stable 1.12.X?

~~~
x25519
No, new features don't usually get backported to the stable branch.

It will ship with 1.13.9 (mainline) in 6 hours (at the time of writing).

For stable branch, you need to wait until the 1.13 milestone is completed,
which according to their roadmap
([https://trac.nginx.org/nginx/milestone/1.13](https://trac.nginx.org/nginx/milestone/1.13))
will be completed in 8 weeks.

------
steeve
Still no HTTP/2 backend support?

~~~
x25519
No.

Maxim's answer on this issue:
[https://mailman.nginx.org/pipermail/nginx/2015-December/0494...](https://mailman.nginx.org/pipermail/nginx/2015-December/049445.html)

