The PWA Philosophy

Matt Wilber


What is a PWA?

“Progressive Web Apps (PWAs) are web applications that load like regular web pages or websites but can offer the user functionality traditionally available only to native applications.”

-- The Book of Knowledge (Wikipedia)

Why Go PWA?

  • Improve web experience
  • App store politics

    • Crowded marketplace

    • Difficult to differentiate

    • Review process

  • Leverage existing search ranking

  • Low barrier to entry

    • Use existing web technology

    • Works on all platforms

  • Small Footprint

PWAs are

much more

than that

The PWA Philosophy

  • Accessibility

  • Performance

  • Native features

Progressive Web Apps make an adaptive experience that fits as diverse an audience as possible.

Focusing on:

Accessibility means

bigger audience

  • People consume information in different ways.

    • Text, Images, Sound.

  • Accessibility is not an add-on.

    • Present your information in as many ways as possible.

    • Don't accommodate disabilities, embrace different perspectives.

  • Leverage established techniques:

    • Responsive design

    • Semantic HTML

Performance saves users & bandwidth

  • You have 4 seconds to get their attention.

  • Prioritize features.

    • Basic functionality available right away.          

    • ​Lazy load everything else.

  • Cache static files.

    • Pull new content in the background.

  • Optimize graphics.

    • Use SVG where possible.

    • Limit web fonts.

Modern browsers afford native features

  • Web Manifest (Installation)

  • Service Worker

    • Fetch API

    • Cache API

    • Sync API

    • Push Notifications

  • LocalStorage / IndexedDB

  • Location API

  • GetUserMedia()

3 Minimum Requirements to qualify as a PWA

  • SSL

  • Service Worker

  • Web Manifest

Turn any website into a PWA

in 10 minutes

( assuming SSL )

Add Web Manifest

	"name": "GreenZeta Progressive Web App Demo",
	"short_name": "GZ PWA",
	"theme_color": "#7bb951",
	"background_color": "#111313",
	"display": "fullscreen",
	"Scope": "/",
	"start_url": "/",
	"icons": [
		"src": "/assets/icons/icon-192x192.png",
		"sizes": "192x192",
		"type": "image/png"
	"splash_pages": null

Add Metadata Alternative

<meta name="viewport" content="width=device-width">
<meta name="apple-mobile-web-app-capable" content="yes" />

<meta name="theme-color" content="#7bb951">
<meta name="mobile-web-app-capable" content="yes">
<link rel="apple-touch-icon" href="assets/icons/icon-512x512.png">
<link rel="apple-touch-icon" sizes="72x72" href="assets/icons/icon-72x72.png">
<link rel="apple-touch-icon" sizes="144x144" href="assets/icons/icon-144x144.png">
<link rel="apple-touch-icon" sizes="512x512" href="assets/icons/icon-512x512.png">

Register Service Worker

if ('serviceWorker' in navigator) {
	window.addEventListener('load', () => {
                    .then(registration => {
		    	console.log('SW registered: ', registration);
		    }).catch(registrationError => {
		    	console.log('SW registration failed: ', registrationError);

Add A Caching Strategy

self.addEventListener('install', function(event){
    console.log('[SW] installing...');
            console.log('[SW] precaching');

self.addEventListener('fetch', function(event){
                    return response;
                    return fetch(event.request);

Install Prompt

let deferredPrompt;

window.addEventListener('beforeinstallprompt', (e) => {
	// Store the install prompt event
	deferredPrompt = e;
	console.log('install prompt ready');

document.getElementById('install').addEventListener('click', (e)=>{
	// Show the prompt
	// Wait for the user to respond to the prompt
		.then((choiceResult) => {
		if (choiceResult.outcome === 'accepted') {
			console.log('User accepted the prompt');
		} else {
			console.log('User dismissed the prompt');
		deferredPrompt = null;

How to approach building a PWA

War of the Worlds Broadcast

  • 2012 - Began as HTML5 audio demo

  • 2018 - Rebuilt as a PWA

Rethinking the website as a PWA

  • App Shell

    • In-line svgs

    • In-line javascript

    • Minimal necessary CSS

  • Eliminate jQuery

    • document.QuerySelector()

    • fetch()

Responsive Design

  • Graphically rich layout needed to look good at any resolution.

  • Combination of scaling and re-positioning

  • Moving previous control overlay to an action button + slide-out menu



App Shell

  • index.html - 10k in size. Contains everything to display a minimally usable app.
  • First meaningful paint - inline svg, action button, menu w/ description

Lazy Loading

  • Don't make user wait for entire site to load.
    • Audio streams while images are loading
  • Provide indication that more is coming.
    • Entertaining progress bar

Native Features

  • Offline Access

  • WebAudio API

  • Chromecast

  • Push Notification


  • Lighthouse, available through Chrome dev tools.
  • Don't get hung up with the scores.

Source Code

Check Out

Follow @greenzeta on Twitter


Google PWA Checklist

The Progressive Web App Philosophy

By Matthew Wilber

The Progressive Web App Philosophy

From the 2/12/19 Fredericksburg Developer Group meeting.

  • 1,774