Skip to content

HTTP/2 Server push support #91

@janwerkhoven

Description

@janwerkhoven

I believe Fastboot could be serving assets even faster if it were leverage HTTP/2 sever push.

Background

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.

That's perfect for an Ember app because we always have 4 predictable files that need to be loaded:

ember-app.js
ember-app.css
vendor.js
vendor.css

The idea

The idea is to push these 4 files along with the index.html to the client instead of waiting for index.html to land, then fire 4 request, then wait for those requests to land.

Nginx

In Nginx you can specify files to push with http2_push:

server {
  listen 443 ssl http2;
  listen [::]:443 ssl http2;

  server_name foo-app.com;

  location / {
    # Pass requests to Fastboot
    proxy_pass http://0.0.0.0:8000;

    # Leverage HTTP/2 server push
    http2_push /assets/lmpa-interflux-com-dd56fc256fbb789e812d33c1ca0a2cdb.css;
    http2_push /assets/outdatedbrowser.min-9131a0c1fc3c983e7770d2a8978ffbb4.css;
    http2_push /assets/lmpa-interflux-com-e99f983e06bc16d6677864b25e1f0e4f.js;
    http2_push /assets/vendor-743626574e3ff471643e8686d1be9635.js;
    http2_push /assets/outdatedbrowser.min-29fcaeff82d07e196a8d053f0601fcc4.js;
    http2_push /assets/fonts/lato/subset-Lato-Regular.woff2;
    http2_push /assets/fonts/lato/subset-Lato-Bold.woff2;
    http2_push /assets/fonts/lato/subset-Lato-Black.woff2;
  }
}

Pre-emptively pushing these files increase my project's load times from:

screen shot 2018-10-27 at 00 30 21
screen shot 2018-10-27 at 00 30 29

To:

screen shot 2018-10-27 at 00 22 27
screen shot 2018-10-27 at 00 22 19

Before:

screen shot 2018-10-27 at 00 33 39

After:

screen shot 2018-10-27 at 00 33 31

That's amazing! 🌮

Do give me more! 🙏

Caveat

The Ember files are fingerprinted... Which is great for busting caches when deploying new fixes, but that also breaks having set static http2_push paths.

Bad solution

Stop fingerprinting files in order to leverage static http2_push. 🔥

Is bad because busting caches is arguably more important.

Beter solution

Since NGINX 1.13.9 support was http2_push_preload on; which automatically HTTP/2 server pushes files marked by the Link header.

That means in Nginx setting:

  location / {
    proxy_pass http://0.0.0.0:8000;
    http2_push_preload on;
  }

And having Fastboot somehow add the following response header when fetching index.html:

Link: "</assets/foo-app-e99f983e06bc16d6677864b25e1f0e4f.js>; as=script; rel=preload, </assets/foo-app-e99f983e06bc16d6677864b25e1f0e4f.css>; as=style; rel=preload"

Would preload this JS and CSS file.

Feature request?

  1. Is there a way to add the Link header to each Fastboot responses?

  2. Does Fastboot have an index of the fingerprinted files we can concatenate into the Link header?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions