fastboot-app-server icon indicating copy to clipboard operation
fastboot-app-server copied to clipboard

HTTP/2 Server push support

Open janwerkhoven opened this issue 7 years ago • 3 comments

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?

janwerkhoven avatar Oct 26 '18 14:10 janwerkhoven

@janwerkhoven this looks awesome. But this project hasn't had any love in 8 months and I've never gotten a response on any PR in over a year. Maybe fork it?

mhluska avatar Oct 31 '18 06:10 mhluska

@mhluska Thanks, I'd love to contribute.

I think I first will have to learn more about Node, Express and Fastboot internals though... 😅

Was hoping someone with experience would point in the right direction.

janwerkhoven avatar Nov 02 '18 00:11 janwerkhoven

This would be sweeeeeeet.

rynam0 avatar Feb 07 '19 21:02 rynam0