I always want my websites to be secure and fast. HTTP/2 is the latest enhancement to the HTTP protocol that can provide significant performance improvements:
The primary goals for HTTP/2 are to reduce latency by enabling full request and response multiplexing, minimize protocol overhead via efficient compression of HTTP header fields, and add support for request prioritization and server push.
It turns out all browsers that support HTTP/2 also require TLS (HTTPS). So my first step was adding HTTPS support to agilitycourses.com which also provides a backbone on which I'll implement secure user profiles. Then I wanted to enable HTTP/2 to see if it improved the speed of pages served to end users.
After a little research I found that recent releases of NGINX support HTTP/2 and those versions are packaged with Ubuntu 16.04 LTS. That made upgrading to this latest long term support OS version a better approach than just upgrading NGINX on my older OS. I basically went through the standard upgrade process.
While I had to work through a number of small issues upgrading my older websites; the biggest change was converting my upstart scripts to systemd scripts. But the beauty of hosting with virtual servers is it was trivial to create an image of my existing server, spin up a temporary server using that image, and then practice the ugprade/migration on the temporary server. I was able to move some configuration changes back to my live server and test out the changes to my sites' Fabric deployment scripts.
Once everything was working I configured my websites that contain user modifiable data into maintenance mode on my temporary server. Then I pointed the DNS for all my domains to the temporary server. After DNS propagated I shutdown Postgres and the webserver on my original server and created a backup image. Then I went through the upgrade process. Once I validated the migration was successful I switched the DNS back to my original server and shutdown the temporary server. After a couple days I deleted the temporary server and the pre-migration backup image.
Once I was on NGINX version 1.10 the change to the website to enable HTTP/2 was as simple as changing the virtual server from:
server { listen 443 ssl; listen [::]:443 ssl; ... }
to:
server { listen 443 ssl http2; listen [::]:443 ssl http2; ... }
Then I just reloaded the Nginx configuration: sudo systemctl reload nginx. That was it!
Here's the network view of the timing of requests for a page using HTTP/1.1 over HTTPS in Chrome:
Here's the same page using HTTP/2 over HTTPS:
The obvious difference is in the Timeline - Start Time column. In the first diagram you can see the "waterfall" queueing up of requests for images as all the open sockets to the domain were in use. In the second diagram you can see them all interleaved as they are multiplexed across the same connection.
Also the bottom line is the page is fully loaded in 1.73 sec using HTTP/1.1 and in 1.16 sec using HTTP/2 for a 33% end user page load improvement!
So that was a nice free speed up and there are plenty of areas I can still investigate to further improve the performance of this web site: