HTTP/2 Server Push with NGINX
Server push allows a server to pre‑emptively push resources to a remote client, anticipating that the client may soon request those resources.
Server push, which is defined in the HTTP/2 specification, allows a server to pre‑emptively push resources to a remote client, anticipating that the client may soon request those resources. By doing so, you can potentially reduce the number of RTTs (round trip time – the time needed for a request and response) in a page‑load operation by one RTT or more, providing faster response to the user.
Automatically Pushing Resources to Clients
NGINX supports the convention of intercepting Link preload headers, then pushing the resources identified in these headers. To enable preload, include the http2_push_preload
directive in the configuration
server {
listen 443 ssl http2;
ssl_certificate ssl/certificate.pem;
ssl_certificate_key ssl/key.pem;
root /app;
location = / {
proxy_pass http://upstream;
http2_push_preload on;
}
}
When NGINX is operating as a proxy (for HTTP, FastCGI, or other traffic types), the upstream server can add a Link header like this to its response:
Link: </style.css>; as=style; rel=preload
NGINX intercepts this header and commences a server push of /style.css
. The path in the Link header must be absolute – relative paths like ./style.css
are not supported. The path can optionally include a query string.
To push multiple objects, you can provide multiple Link headers, or, better still, include all objects in a comma‑separated list.
If you don’t want NGINX to push a preloaded resource, add the nopush parameter to the header:
# Resource is not pushed
Link: </nginx.png>; as=image; rel=preload; nopush
When http2_push_preload
is enabled, you can also initiate preload server push by setting the response header in your NGINX configuration:
add_header Link "</style.css>; as=style; rel=preload";
Verifying HTTP/2 Server Push
Verifying with Developer Tools (Google Chrome)
The Initiator column on the Network tab of Chrome’s Developer Tools indicates that several resources were pushed to the client as part of a request for /
.
The Initiator column indicates server push was used to send resources
Verifying with a Command-Line Client nghttp
In addition to web browser tools, you can use the nghttp
command‑line client from the nghttp2.org project to verify that server push is in effect. You can download the nghttp
command‑line client from GitHub, or install the appropriate operating system package where available. For Ubuntu, use the nghttp2-client
package.
nghttp -ans https://daliborgogic.com
***** Statistics *****
Request timing:
responseEnd: the time when last byte of response was received
relative to connectEnd
requestStart: the time just before first byte of request was sent
relative to connectEnd. If '*' is shown, this was
pushed by server.
process: responseEnd - requestStart
code: HTTP status code
size: number of bytes received as response body without
inflation.
URI: request URI
see http://www.w3.org/TR/resource-timing/#processing-model
sorted by 'complete'
id responseEnd requestStart process code size request path
13 +52.55ms +175us 52.37ms 200 3K /
2 +87.54ms * +51.07ms 36.48ms 200 1K /_nuxt/5b7fe7c15c2c9b5a934b.js
8 +87.83ms * +51.16ms 36.67ms 200 923 /_nuxt/1379e1f75a0348fc3050.js
6 +118.19ms * +51.14ms 67.04ms 200 16K /_nuxt/72a8068a8157c768035a.js
15 +156.32ms +52.58ms 103.74ms 200 1K /favicon.ico?v=1552306459
4 +161.04ms * +51.12ms 109.92ms 200 53K /_nuxt/3591e1b426a81d4d3c43.js