The PWA Philosophy

Matt Wilber

@greenzeta

greenzeta.com

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

Start with an experience that works in every browser. Then progressively enhance that experience with features, as the platform permits.

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', () => {
		navigator.serviceWorker.register('service-worker.js')
                    .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...');
    event.waitUntil(caches.open('static')
        .then(function(cache){
            console.log('[SW] precaching');
            cache.addAll([
                '/',
                '/index.html'
            ]);
        }));
});

self.addEventListener('fetch', function(event){
    event.respondWith(
        caches.match(event.request)
            .then(function(response){
                if(response){
                    return response;
                }else{
                    return fetch(event.request);
                }
            })
    );
});

Install Prompt
(optional)

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
	deferredPrompt.prompt();
	// Wait for the user to respond to the prompt
	deferredPrompt.userChoice
		.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

Desktop

Phone

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

Optimization

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

Source Code

github.com/mwilber/gz-10-minute-pwa

Check Out

waroftheworldsbroadcast.com

Follow @greenzeta on Twitter

Slides

slides.com/greenzeta/pwa-philosophy

greenzeta.com

Google PWA Checklist

developers.google.com/web/progressive-web-apps/checklist

The Progressive Web App Philosophy

By Matthew Wilber

The Progressive Web App Philosophy

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

  • 134
Loading comments...

More from Matthew Wilber