GoogleChromeLabs/http2push-gae

Name: http2push-gae

Owner: GoogleChromeLabs

Description: Drop-in HTTP2 push on App Engine

Created: 2015-09-09 20:51:59.0

Updated: 2018-05-01 05:00:21.0

Pushed: 2016-11-24 01:38:17.0

Homepage: https://http2-push.appspot.com/

Size: 793

Language: HTML

GitHub Committers

UserMost Recent Commit# Commits

Other Committers

UserEmailMost Recent Commit# Commits

README

HTTP 2.0 push on App Engine

This project contains a drop-in library for doing HTTP2 push on Google App Engine.

Demo test site: https://http2-push.appspot.com/

TL;DR how it works
  1. Generate a push_manifest.json using a node script, http2-push-manifest. See below.
  2. Annotate your request handlers with the @http2push.push() decorator.

How this works

Requirements & Setup
  1. App Engine Python SDK. You'll want the dev server for testing.
  2. Node

The example server is written in Python. If you'd like to see other App Engine runtimes feel free to submit a pull request or visit the EXPLAINER to read up on how to construct the Link rel=preload header yourself.

Run the example server(s)

Important the dev server does not support http2 push. An app needs to be deployed to production App Engine.

example/ contains a fully working example of an App Engine Python server and Go servers. This walk-through will use the Python server, which uses the http2push.py library. You'll also see an example examples/python/push_manifest.json in that folder.

To try the test server, start the App Engine dev server in the example folder:

cd example/python
dev_appserver.py --port 8080 .

Open http://localhost:8080/.

Installing in your project
  1. Get the drop-in library: git clone https://github.com/GoogleChrome/http2push-gae
  2. Move http2push-gae/http2push.py into your project folder.
  3. Install http2-push-manifest script: npm install http2-push-manifest --save-dev
Usage
Generating a push manifest

This project uses http2-push-manifest to generate the list of files to push. The JSON file is loaded by http2push.py to constructor the Link header.

Re-run the script whenever your list of resources changes. An easy way to do that is by adding a script to your project's package.json.

For example, assuming app/index.html is your main page, you could add:

"scripts": {
  "push": "http2-push-manifest -f app/index.html"
}

An run npm run push to re-generate the file.

Readhttp2-push-manifest's full documentation for more information on generating the manifest.

Drop in the http2push server module

The http2push.py module provides a base handler and decorator to use in your own server. The decorator is the simplest to integrate. Handlers which are annotated with the @http2push.push() decorator will server-push the resources in push_manifest.json.

Tip - when testing your pages, the ?nopush URL parameter disables push. Use this parameter to test the effectiveness of server push on your own resources or to run performance tests at webpagetest.org.

Example - using the decorator:

app.yaml:

ime: python27
version: 1
adsafe: yes

aries:
me: webapp2
rsion: latest

lers:

l: /css
atic_dir: static/css
cure: always

l: /js
atic_dir: static/js
cure: always

l: .*
ript: main.app
cure: always

main.py:

rt os
rt webapp2

 google.appengine.ext.webapp import template
rt http2push as http2

s Handler(http2.PushHandler):

ttp2.push() # push_manifest.json is used by default.
f get(self):
# Resources in push_manifest.json will be server-pushed with index.html.
path = os.path.join(os.path.dirname(__file__), 'static/index.html')
return self.response.write(template.render(path, {}))

= webapp2.WSGIApplication([('/', Handler)])

To use a custom manifest file name, use @http2push.push('FILENAME').

Example - using a custom manifest file:

rt http2push

s Handler(http2push.PushHandler):

ttp2push.push('custom_manifest.json')
f get(self):
...

For more control, you can also set the headers yourself.

Example - Explicitly set Link: rel=preload (no decorators):

rt http2push

s Handler(http2push.PushHandler):

f get(self):
# Optional: use custom manifest file.
# self.push_urls = http2push.use_push_manifest('custom_manifest.json')

header = self._generate_link_preload_headers()
self.response.headers.add_header('Link', header)

path = os.path.join(os.path.dirname(__file__), 'static/index.html')
return self.response.write(template.render(path, {}))
Pushing content from a static handler

If you don't have a dynamic script handler, you can still push resources from App Engine page by setting the http_headers on your static page handler in app.yaml.

app.yaml:



lers:

l: /css
atic_dir: static/css
cure: always

l: /js
atic_dir: static/js
cure: always

l: /$
atic_files: path/to/index.html
load: path/to/index.html
tp_headers:
Link: '</js/app.js>; rel=preload; as=script, </css/app.css>; rel=preload; as=style'
Deployment (test site)

Note: this section is only for maintainers of this project.

Build it

There's a one-stop convenience script to vulcanize the app and generate push_manifest.json:

cd site
./scripts/build.sh
Deploy it

Run deploy.sh to deploy the demo site. Note: build.sh is ran as part of this process.

./scripts/deploy.sh <VERSION>

Where <VERSION> is the app version you'd like to deploy as.


This work is supported by the National Institutes of Health's National Center for Advancing Translational Sciences, Grant Number U24TR002306. This work is solely the responsibility of the creators and does not necessarily represent the official views of the National Institutes of Health.