Getting Started with HTTP/2 and Server Push

HTTP/2 is awesome. When we enabled HTTP/2 on the settled.co.uk website, we noticed a 10% improvement in the page load times across the site. We didn’t change any code, or even make any web performance tweaks - we made the switch and noticed the results immediately.

Traditionally, HTTP/1.1 requests have a lot of overhead associated with them. If too many requests are made, it can negatively affect the performance of your web page due to the fact that HTTP/1.1 uses multiple TCP connections to issue parallel requests. Fortunately, HTTP/2 has been redeveloped with this in mind, allowing the browser to multiplex requests. This means that instead of limiting the number of parallel connections, multiple requests can be sent at one time.

HTTP/2 Server Push

Multiplexing allows multiple request and response messages to be in flight at the same time which means faster load times with no change to your front end code. A lot of the web performance hacks that we currently use are no longer needed!

One of my favourite features of HTTP/2 is Server Push. With HTTP/1.1, the browser requests a web page, the server sends the HTML in the response, and then it needs to wait for the browser to parse the HTML and issue requests for all of the embedded assets before it can start sending the JavaScript, images and CSS. This is where Server Push is a game changer. Instead of waiting for the HTTP response, it allows the server to “push” the resources it thinks the client will need into its cache.

If you’ve not had the chance to experiment with HTTP/2, getting started is easier than you think. In this article I am going to show you how you can create a simple website that uses HTTP/2 and Server Push.

Show me the code!

Let’s have a look at this basic web page example below.

The code above is a pretty basic and simply references an image as well as two JavaScript files. These two files aren’t anything fancy, they log basic data to the console once they have been downloaded and parsed.

To get started, you’ll need to have Node.js installed. This example also uses Express as a web framework for Node.js. If you aren’t familiar with Express, the documentation is very thorough.

We are also going to be using the awesome node-spdy module that provides you with support for HTTP/2 and Express. Finally, I’ve used the mz library, in order to get the most out of JS Promises and ES6.

Okay, it’s time to start coding! Start off by firing up your terminal and installing all of these packages with the following command in your terminal. I’ve chained them together for ease of use:

$ npm install express spdy mz --save

Next, let’s setup a file that will be the entrypoint for our app. I’ve added the following code and named the file “app.js”.

Let’s break the above code above down a little. The code starts off by referencing the express framework. Next, it creates a route that will respond with the home.html file and serves it as an HTTP response.

Around line 19, you’ll notice that I am creating a new server using the node-spdy module. HTTP/2 requires you to serve resources over HTTPS in order to improve security. To test this code locally, I created my own self signed certificates using OpenSSL - you can do this using a one line command in your terminal.

openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout server.key -out server.crt

On a production environment, you would use the correct SSL certificates, but for now this will work fine for testing locally. Next, fire up your browser and head over to http://localhost:8000/home. If you open up your developer tools, you should now be serving the website over HTTP/2!

HTTP/2 Server Push Dev Tools

Push it. Push it real good

Things are looking good so far. We’ve created an HTTP/2 server that is serving resources, but we aren’t “pushing” any resources to the user yet.

In order to start using Server Push, we need to update the code slightly.

Around line 10, you’ll notice that I’m using the Promise.all function to read in the JavaScript files and the HTML page itself. When the reads are complete, I then check to see if the current browser supports HTTP/2 push. If it does, I push the resource into the response as a stream along with the content type in the HTTP response headers. If you fire up your dev tools again and look at the network requests you’ll notice that we are now pushing the resources at the same time as the request.

HTTP/2 Server Push

The console will show the results of the scripts executing. That’s it - using the code above, we are now serving files over HTTP/2 using Server Push!

Summary

Using HTTP/2 and Server Push is a great way to provide your users with faster web pages. The great thing about the node-spdy module is that it will fallback to regular HTTPS for browsers that don’t support HTTP/2.

If you’d like to explore the code used in this example, it is all available on my Github repo. Regardless of whether you use a PC or a Mac this example will have you serving faster web pages to your users in no time!








Comments

Rob - 10/28/2016
You don't need any of those libraries or frameworks to do http/2 push. I was hoping this article would go into that rather than just cobbling pieces together.

Brian P. - 10/30/2016
Great article Dean - never knew it was this easy to get started with HTTP/2. I'll be trying this out for sure!

Ferdinand Mütsch - 11/9/2016
Another way to enable a website with HTTP/2 and server push is to set an nghttpx (https://nghttp2.org/documentation/nghttpx-howto.html) reverse proxy in front of it and then set a Link preload header at application level for the respective assets to be server-pushed.

Gleb Bahmutov - 1/4/2017
Good explanation. How can one work with push events if the express server is NOT SSL terminator? Commonly the express is only doing the logic, while something like nginx is handling SSL termination.

Markus - 2/17/2017
seems like you successfully demonstrated how a page will get slower when using http server push.. All perf related numbers in your screenshot got worse when server push is enabled...?


Add your comment

300 Characters left


Please fill this in to confirm that you are human