Moving towards performance with HTTP/2

@Webapp builders Meetup

Jull Weber
Jull-Allan Weber Sanfiorenzo


Bayamon, Puerto Rico
2000 MIT Graduate
Monkey Kode, Danceraccess
PHP, JS, and I like server stuff
Curious Facts:
  1. Was obsessed with building 2000 piece jigsaw puzzles when i was 4.
  2. Went to Space Camp and witnessed my first tornado at 11. I didn't fly away, Thank God. The golden medal made me feel better.
  3. Took hiatus to dance professionally. Went on tour dancing with Madonna.

Dancing Coder

A little history



  • HTTP 1.0 is huge. It was released in 1996 and it's grown from 60 to a 176 pages document.
  • In HTTP 1.1, multiple requests queue up behind each other, creating the famous waterfall effect.
  • HTTP 1.1 is latency sensitive, lots of users with fast connections still suffer from slow latency.
Waterfall effect
HTTP Waterfall effect

Understanding the HTTP request


  1. DNS resolution
  2. TCP connection handshake
  3. TLS negotiation (if required)
  4. dispatch the HTTP request
  5. content download
HTTP hanshake

Performance matters

Load drop time

Our sites are huge

By 2016, the average size of a website is 2.4MB. Page load bytes
Average page size x pages x visitors

If you are pushing 2.4MB x 1 x 1000 = 2.4GB

If you are pushing 2.4MB x 4 x 1000 = 9.6GB

  • Bandwidth can get expensive, so poorly performant sites can get very costly.
  • Search engine rank and weigh sites based on their mobile performance.

Current workarounds to overcome latency pains

  • Following standards and using native browser CSS.
  • Serving Critical CSS and JS first (above the fold).
  • Spriting: combining and compressing images into one file.
  • Inlining: embedding files with data uri.
  • Concatenation: merging all your js/css assets.
  • Sharding: serving assets on as many different hosts as possible. TCP connections MAX=2.
  • Pipelining: sending another request while waiting for the response to a previous request.

Wouldn't it be nice if:

  • Be less latency sensitive.
  • Fix pipelining and the head of line blocking problem.
  • Eliminate the need to keep increasing the number of connections to each host.
  • Keep all existing interfaces, all content, the URI formats and schemes.

HTTP/2 to the rescue

HTTP/2 Superhero

HTTP/2 Support

Currently ~79.42% browser support

Browser Support
  • Started from SPDY, protocol spearheaded by Google.
  • HTTP/2 is a binary protocol making it simpler.
  • HTTP/2 is https:// only (Respect users' privacy and higher success rate)
  • Multiplexing: A single http2 connection can contain multiple concurrently-open streams, with either endpoint interleaving frames from multiple streams.
  • HTTP/2 offers Server Push or "cache push." If you the client asks for resource X, the server may know they want Z and sends it without being asked.



HTTP/2 Requirements

  1. Server support for HTTP/2 + all features
  2. Encrypted HTTPS connection through SSL
    1. SSL Certificates are available for free from vendors like OpenSSL and Lets Encrypt.
  3. Browser Support for HTTP/2

Optimizing for HTTP/2

  • Compress images.
  • Modularize minified CSS and Javascript in smaller files.
  • Cache CSS and Javascript that is unlikely to change.
  • User server push to provide the browser with required files before it knows it needs them.

Moving towards performance

How do we do this?


Images Load graph

Image Performance

  • When it comes to images on the web, less is more.
  • Stay away from sliders/carousel unless they are absolutely positively integral to the user experience (which is never).
  • Manually Optimize your images: Blur unnecessary areas, export with low compression
  • Use responsive images that are sized to the viewing area.
  • Automate Image Optimization

Choose the right Image format

  1. Giff: Never use it
  2. JPEG: lossy, progressively loads, low file size, universal support, does not scale.
  3. PNG- alpha transparency
  4. SVG- Not image bitmaps, code-base. Fastest.
  5. Webp- google format with transparency, better but not widely supported

Code Optimization

  1. Minify everything
  2. Concatenation of CSS/JS is now an antipattern.
  3. Critical loading matters. Defer/async when you can.
  4. Use front end tools and the command line (gulp, grunt, webpack) to automize minification and compression.

Modularize CSS

Completely rethink your CSS. So this:
                        @import 'CSS/header';
                        @import 'CSS/menu';
                        @import 'CSS/frontpage';
                        @import 'CSS/promo';
                        @import 'CSS/stories';
                        @import 'CSS/footer';
                        @import 'CSS/flexslider';

Becomes this:


Defer CSS

In Javascript we use defer/async, but how do you do it CSS. Javascript to the rescue. Tag above

Bleeding edge CSS loading

The future of loading CSS by Jake Archibald


Optimizing JS

  1. JS still belongs at the bottom of the page.
  2. Appending the Async attribute allows the browser to keep parsing the html, but you don't have control when the scripts start executing.
  3. Defer completely delays the execution of the javascript until the html is fully parsed. Execution is from top down.

Regular Js is render blocking.

Regular Js

Async stops blocking.

Regular Js

Defers delays execution.

Defer Js

Rule of thumb

Pretty much async all javascript unless you need control of execution


Performance testing

These all give different reports. Test against all.
  1. Google Page Speed: Detailed info on how to improve your site.
  2. Wep Page Test: In depth statistics on your site. Film strip view option.
  3. Pingdom
  4. GTMetrix

Server Optimizations

  • Enable server-side GZIP
  • Enable selective browser caching
  • Use command line tools for automated cache busting
  • Leverage the potential of HTTP/2 with server push


  • Managed Hosting: user CPanel
  • Wordpress + Drupal have plugins and modules for this
  • Manually configure your server settings use HTML5 server configs

Browser Caching

In .htaccess. Experiment with settings. 1 month? up to you.

                        # Cache all the things:
                        # One year for most static assets
                        Header set Cache-Control "max-age=31536000, public"

                        # One month for images
                        Header set Cache-Control "max-age=2628000, public"


Cache busting

  • Bypasses cache and forces files to kick in.
  • Generate file hashes with preprocessors.
    • gulp-rev - gulp revisions
    • Webpack - use build hashing or chunk hashing.
       output: {
              filename: '[name]-[chunkhash:8].js',
              path: 'build/public',
              pathinfo: false,
              libraryTarget: 'umd'

Server Push

Added header rel=preload

Server Push

You can use server side code

Example with PHP

header('Link: ' . $uri . '; rel=preload; as=' . $as, false);

$assets = array(
    '' => 'style',
    '' => 'style',
    '/CSS/header.css' => 'style',
    '' => 'script',
    '' => 'script',
    ''=> 'image'

array_walk( $assets, push_to_browser);


Server Push Strategy

  • Push above the fold assets ( CSS, JS, images, etc)
  • Push external assets (font libraries, JS libraries, etc)
  • Push "next step" pages (if you are certain the visitor will go to this next page)

Use a Content Delivery Network (CDN)

  • HTTPS + HTTP/2 support (with server push)
  • Global Reach
  • Security Features (firewall, DDoS protections, etc)
  • Dismiss Hosting company CDNs, use a 3rd party CDN service that are dedicated CDNs.