Progressive Web Apps

Are The Future

Created by Jared Faris / @jaredthenerd

If you have an Android device, you can try out demos here http://bit.ly/DemoPWA.

Topics

  • Vision of Progressive Web Apps
  • Fetch API
    • Overview
    • GET and POST
    • Comparisons to XHR and jQuery
    • Streaming
  • Service Workers
    • Overview
    • Caching Requests
    • Offline Syncing
    • Push Notifications
  • Other Bits
    • Manifests
    • Additional APIs

Progressive Web Apps

What are PWAs?

¯\_(ツ)_/¯

They're not really a 'thing', at least in terms of standards

Google says:

I say PWAs are:

  • Websites you can find through normal search mechanisms
  • that progressively enhance their functionality
  • to allow them to act as rich applications
  • so your users can do awesome things online and offline.

A lot of things don't need to be apps

What makes up a PWA?

Google's' Checklists

In a nutshell

  • Responsive design that works everywhere
  • Offline support via Service Worker
  • Manifest file providing 'app-like' details

PWA aren't a standard

PWA experience

  • Progressively enhancing existing sites
  • Discoverable through the web
  • Usable like an app

Fetch API

What is Fetch?

Let's read the spec!

The Fetch API is a new, standard way of fetching resources (get it?).


Fetch provides a unified way for you to fetch stuff (like APIs), and for the browser to fetch stuff (like images).

Fetch should replace XMLHTTPRequest (XHR) in most situations...

...except when you need to be able to cancel them

Suddenly, a wild tangent appears!

Promises

Promises are a new (in JS) way of chaining events without callbacks. Yay!

Callback bleh


							myAsyncFunction(dataObject, 
								function(response){ 
									doSomething(response);
								},
								function(error) {
									console.log("Ooops!");
								}
							);
						

Or if we're really good...


							myAsyncFunction(dataObject, successCallback, errorCallback);
						

Or if we're really really bad... pyramid coding


							//asyncCall(successCallback, errorCallback)
							asyncCall(function(data) {
								// if successful, make another call with the data
								asyncCall2(data.someProperty, function(data) {
									// do something
									asyncCall3(data.someOtherProperty, function(data) {
										// do something else
									}
								}, function (data) {
									// error handling
								}
							}, function(data) {
								// error handling
							}
						

With promises


						asyncCall()
							.then((data) => asyncCall2(data.someProperty))
							.then((data) => asyncCall3(data.someOtherProperty))
							.catch((data) => {
								// error handling
							})
                    

Let's look at a demo!

Demo 1a - Simple GET Example

Click Here!

Open scripts/01a-SimpleGET.js

Fetch supports all the verbs you care about: GET, POST, HEAD, PUT, DELETE, OPTIONS.

but wait... there's more!

It also supports CHICKEN!

I couldn't actually make this work in Express

Let's look at a POST demo

Demo 1b - Simple POST Example

Same Place!

Open scripts/01b-SimplePOST.js

How did we get here?

First, there was XMLHTTPRequest (XHR)

Demo 1c - XHR Example

Same Place!

Open scripts/01c-SimpleXHRGET.js

XHR is old and hacky

  • MS created the concept for Outlook Web Access and Exchange 2000
  • Mozilla created a similar structure in late 2000
  • Implementation was mostly standardized by 2005
  • jQuery killed anyone using it directly in 2006

Fetch is old and hacky new and shiny!

  • Requires less code
  • Uses modern JS patterns (promises)
  • Supported in all evergreen browsers

Let's talk features

  • Custom Header and Request objects
  • Response objects you can query
  • Body objects that contain data in various formats

Demo 1e - Custom Headers & Request Options

Open scripts/01e-BrokenOutPOST.js

Response Object

Response Body Mixin

  • .arrayBuffer()
  • .blob()
  • .formData()
  • .json()
  • .text()

Streaming

Streams allow you to get large amounts of data and process it as it loads.

Lots of potential for visualizing real-time data, or doing lots of calculations.

Demo 2 - Streaming

Demo

Open scripts/02a-Streaming.js

Fetch Support

Basic support in all evergreen browsers

Streaming support in Chrome and Edge

Polyfill

Supports basic features

Can't magic in things like streams

Demo 3 - Polyfill

Demo

So When Do I Use This?

Service Workers

Why are they a thing?

Connectivity issues are a big deal on the web


Previous attempts to address this stunk

Note: Not my word choice.

Service Workers provide a flexible way to deal with offline issues


But wait... there's more!

Service workers can let you:

  • Cache assets for offline use
  • Manage network traffic
  • Build retry mechanisms
  • Allow push notifications
  • And world peace!

Are they amazing?

Demo 4 - Caching Offline Content

Click Here!

No Code Yet... Doh!

SW Steps

  • .register called & SW fetched
  • "install" event fires, you setup stuff
  • SW waits to take over pages
  • "activate" event fires, you clean up stuff
  • SW does its thing

skipWaiting (install) & clients.claim (activate)

Let's walk through Demo 4

Open 04-offline-sw.js (it's not in /scripts... wth?)

Wait... what's that cache thing?

Suddenly, a...

Oh, we did that joke

Cache API

A simple way to store Requst and Response objects

The Cache API allows you to:

  • .add a request*
  • .put a request/response pair
  • .delete a request/response
  • .match & .matchAll to search for response(s)
  • Return a list of .keys

Service Workers allow more than just caching

We could:

  • Intercept a bunch of POSTs and bundle them
  • Reduce the frequency of server requests if data isn't changing
  • Inject additional calls for instrumentation
  • Build a local data store to speed things up

Warning: Experimental Syncing Ahead

Background Sync Concepts

  • You trigger a 'sync' event with a tag
  • Listen for the event/tag and connect a Promise to it
  • If the promise succeeds, you're done
  • If the promise fails, a retry is scheduled
  • The browser triggers a 'sync' event if it sees a connection return

About IndexedDB

IndexedDB is:

  • A transactional DB
  • Widly supported
  • Queried with JavaScript
  • Confusing to use

Demo 5 - Handling POSTs when offline

Click Here!

Open 05-offlinePOST-sw.js

Push Notifications


							throw "Salt-n-Pepa Joke Not Implemented"
						
I'm very sorry

Demo 6 - Push Notifications

Click Here!

Open 06-offlinePOSTPush-sw.js

The page doesn't have to be open as long as the browser is.

What's happening here?

  • Application registers with PushManager
  • Subscription ID returned from Promise
  • Application sends the Subscription ID to the server
  • Server uses ID to send messages

In the Wild


Twitter's Service Worker

Support


Is Service Worker Ready?

In general

  • Chrome/Firefox/Opera support core features
  • Background Sync is Chrome only
  • Chrome & Firefox both support Push notifications*
  • Everyone else is working on it

Other Stuff

The Manifest

manifest.json

							{
								"short_name": "MyApp",
								"name": "My Awesome App"
							}
						

HTML file

							<head>
								<!-- other HEAD stuff -->
								<link href="manifest.json" rel="manifest">
							</head>								
						

Demo 7 - PWA

Click Here!

Open manifest.json

Discoverability

  • App Stores
  • Search Engines

Check out HWAs

In summary

Fetch, Service Workers and PWA are definitely cutting edge

They represent a web that's full featured

You can start to use them today via progressive enhancement

So Should You Care?

Yes

Thank You

Created by Jared Faris / @jaredthenerd