Skip to content
  • Services
  • About
  • Partners
  • Work
  • Insights
  • Careers
  • Contact
  • Services
  • About
  • Partners
  • Work
  • Insights
  • Careers
  • Contact
April 10, 2020

Be Pushy with HTTP/2

DevOps, Front End Development, JavaScript

The Hypertext Transfer Protocol (HTTP) is the protocol that transmits hypertext around the Internet and in fact is what was used to deliver this blog to you on your browser. You likely don’t even think about it while checking your Facebook, but it’s really the foundation of the Internet. Version 1.1 is the most widely implemented version of this protocol, but did you know it’s over 20 years old? It could vote or buy alcohol, hopefully not at the same time, but that would explain a lot.

That’s a long time and that’s why version 2 (HTTP/2) was released a couple years ago. HTTP/2 makes many of the workarounds we had to implement to work around the limitations of HTTP/1 obsolete and even anti-patterns (looking at you, image sprites and domain sharding). There are many great improvements, but let’s talk about one that is very interesting and can have some real benefits to the performance of loading a website and that’s server push. What if you could have a 135% boost in load time performance using HTTP/2 server push over the old HTTP/1 way of loading and 12% boost with HTTP/2 without server push? Before you sign on the dotted line, let’s look at it first.

Server is the Boss!

Yes, server push. Instead of simply letting a browser load some HTML and determine what assets to download, we can push assets to the browser. Even though with HTTP/2 we don’t have to worry about how many sockets we are taking up with loading all those animated GIFs, there is still the process of the browser requesting those GIFs to form a round-trip request. But what if we could get rid of half of the request and just push the asset to the browser?

Not so Fast!

Great! So instead of having a request and a response, we just have a response! Yes and no. Browsers still cache assets and we’d hurt performance if we got rid of that caching. We need to know when the browser can load from the cache or needs to load from the server in order to know when we should push assets to the browser. Sounds complicated, doesn’t it? And it is but thankfully the folks at Google have thought of this and created a module that handles all this voodoo for us. All we have to do is implement a server able to serve via HTTP/2 and include this module, it’ll really be that simple!

Getting Fast

Fastify is an up-and-coming Node.js web framework designed to be… fast. It’s nearly as fast as using Node.js’ native HTTP module and almost twice as fast as Express. Fastify is also simple to configure, has lots of plugins and supports HTTP/2. A simple static server would be:

const fastify = require('fastify')
const fastifyStatic = require('fastify-static')
const fs = require('fs')
const path = require('path')

const STATIC_DIR = path.join(__dirname, 'static')
const CERTS_DIR = path.join(__dirname, 'certs')
const PORT = 3000

async function start () {
  const server = fastify({
    http2: true,
    https: {
      key: fs.readFileSync(path.join(CERTS_DIR, 'key.pem')),
      cert: fs.readFileSync(path.join(CERTS_DIR, 'cert.pem'))
    }
  })

  server.register(fastifyStatic, {
    root: STATIC_DIR
  })

  await server.listen(PORT)

  console.log(`Listening on port ${PORT}`)
}

start().catch(console.error)

The one caveat to HTTP/2 is that browsers do require a SSL certificate. You can use the tls-keychain module to create a trusted certificate for local testing.

Load a sample HTML page with a couple assets and in the browser dev tools you can notice h2 is the protocol which means it was indeed loaded via HTTP/2:

Sample HTTP:2

Time to Push

Great, so we have a platform which we can use all the goodies of HTTP/2 but we aren’t pushing assets yet. Fastify has a plugin in order to use Google’s auto-push module called fastify-auth-push and it’s as simple as replacing the fastify-static module. Your server code would now look like:

const fastify = require('fastify')
const { staticServe } = require('fastify-auto-push')
const fs = require('fs')
const path = require('path')

const STATIC_DIR = path.join(__dirname, 'static')
const CERTS_DIR = path.join(__dirname, 'certs')
const PORT = 3000

async function start () {
  const server = fastify({
    http2: true,
    https: {
      key: fs.readFileSync(path.join(CERTS_DIR, 'key.pem')),
      cert: fs.readFileSync(path.join(CERTS_DIR, 'cert.pem'))
    }
  })

  server.register(staticServe, {
    root: STATIC_DIR
  })

  await server.listen(PORT)

  console.log(`Listening on port ${PORT}`)
}

start().catch(console.error)

Only two lines were changed but looking at the dev tools when loading using this new server code, you can see the Initiator column has changed to show that the assets were pushed:

Sample HTTP:2 Initiator Column

Conclusion

With very little changes, we implemented HTTP/2 server push, which is a cool buzzword! With a small test, the server push did cost us loading time on the HTML page but you can see the time it took to load the individual assets decreased even by 80%. Imagine a real website, you will undoubtedly have lots of assets, which would compound the overall savings. That’s where the Node.js Foundation has said they have seen about 12% improvement over delivering via HTTP/2 without server push. What kind of sites have you built where load times suffer because of waiting for assets to load, where pushing from the server could really help?

Posted in DevOps, Front End Development, JavaScript
Share this

Mitchell Simoens

Mitchell Simoens is a Senior Front End Engineer at Modus Create. Mitchell has spent the last 10 years working with Ext JS including developing core functionality, Sencha Fiddle and (I hope your insurance covers blown minds) supporting the online community with over 40,000 posts on the Sencha Forums. Before working with Ext JS, Mitchell used Perl and PHP but loves spending time with Node JS for today's needs. When not working, you can find Mitchell relaxing with his wife and daughter, or developing his talents as an amateur furniture maker.
Follow

Related Posts

  • A JavaScript Developer's Take on Apple's Swift
    A JavaScript Developer's Take on Apple's Swift

    This year Apple succeeded in making their 2014 WWDC one of the key talking points…

  • 4 Key Concepts to Learning ReactJS
    4 Key Concepts to Learning ReactJS

    At Modus Create, our culture is defined by a few key objectives, including the value…

Subscribe to the Modus Newsletter

Receive the latest blog articles and insights every month from the Modus team.

Let's Chat

If forms aren’t your thing, you can always call us (+1-855-721-7223).

Modus-Logo-Primary-White.svg
  • Services
  • About
    • Newsroom
  • Partners
  • Work
  • Insights
    • Blog
    • Modus Labs
  • Careers
Virginia (US)

12100 Sunset Hills Road
Suite 150
Reston, Virginia, 20190
Tel: +1-855-721-7223

California (US)
12130 Millennium Dr

Los Angeles, CA 90094

Missouri (US)
609 E High St

Jefferson City, MO 65101

Romania

Str. Mihai Veliciu, no. 17
Cluj-Napoca, Romania
Tel: +40-0786-887-444

Costa Rica

2nd Floor, Plaza Koros, Av 3
San José, Santa Ana, Costa Rica

© 2021 Modus. All Rights Reserved.

Privacy Policy | Accessibility Statement | Sitemap

This website uses cookies.
These cookies are used to collect information about how you interact with our website and allow us to remember you. We use this information in order to improve and customize your browsing experience, and for analytics and metrics about our visitors both on this website and other media. To find out more about the cookies we use, see our Privacy Policy.

Accept
Privacy & Cookies Policy

Privacy Overview

This website uses cookies to improve your experience while you navigate through the website. Out of these cookies, the cookies that are categorized as necessary are stored on your browser as they are essential for the working of basic functionalities of the website. We also use third-party cookies that help us analyze and understand how you use this website. These cookies will be stored in your browser only with your consent. You also have the option to opt-out of these cookies. But opting out of some of these cookies may have an effect on your browsing experience.
Necessary
Always Enabled

Necessary cookies are absolutely essential for the website to function properly. This category only includes cookies that ensures basic functionalities and security features of the website. These cookies do not store any personal information.

Non-necessary

Any cookies that may not be particularly necessary for the website to function and is used specifically to collect user personal data via analytics, ads, other embedded contents are termed as non-necessary cookies. It is mandatory to procure user consent prior to running these cookies on your website.

Scroll To Top