Live version of slide deck

Progressive Web 


Brian Capouch

Danilo Zekovic


This is experimental technology

Game Plan:

  • Overview of basic concepts
  • A look at critical components
  • Hands-on demonstrations 

What is a PWA?

  • A website with "special sauce"
  • Goal is more "appy" user experience
    • Proxy-like capability
    • Installs to device homescreen
    • Servers can "push" notifications

The special sauce

  • It is called a service worker
  • Installs itself into the browser
  • Maintains a local resource cache
  • Intercepts web fetch requests
  • Receives push notifications

Service Worker

  • A module of JavaScript code
  • Cannot access the DOM!!
  • Runs independently of the page that installed it.
  • Responds to a variety of events

PWA Requirements

  • Must run over HTTPS
  • A manifest file is required
  • Service workers follow "lifecycle" rules
    • Activate on second visit to site


  • Service workers have dedicated, named caches
  • Caches never expire
  • They implement the three basic functions
    • Store
    • Retrieve
    • Remove

Push Notifications

  • Complex in conception and execution
  • User must explicitly allow notifications
  • Client can subscribe/unsubscribe at will
  • Client must possess VAPID key
  • Subscription is to browser, not server

Notifications, con't

  • Client must send subscription to server
  • Server does not send notification!!
    • Messaging server handles actual push
    • Messaging server "belongs" to browser
  • Subscriptions technically never expire

Push-NotifyEvent flow:

  1. User chooses to allow notifications
  2. Client, using VAPID key, requests subscription
  3. Client informs server of subscription details
  4. Site administrator invokes push-notify function
  5. Suscription, key pair, payload sent to messaging server
  6. Messaging server delivers notification to service worker
  7. Service worker logic notifies user of notification

Resource Links

Live Demo Time!!

We will show:

  • Service worker "proxy caching"
  • Generating VAPID and SSL
  • Subscribing 
  • Let's try a push notification
Service worker code to implement proxy cache - ~/public/sw.js:21

self.addEventListener('fetch', function(event) {
  console.log('SW Intercepting: ' + event.request.url);
    caches.match(event.request).then(function(response) {
      // Cache hit - return response
      //return response || fetch(event.request);
      if (response){
        console.log("Returning cached value for: " + event.request.url);
        return response;
      // No hit; fetch resource
      return fetch(event.request);

// Service routines to handle subscription activities
function subscribeUser() {
  const applicationServerKey = urlB64ToUint8Array(applicationServerPublicKey);
    userVisibleOnly: true,
    applicationServerKey: applicationServerKey
  .then(function(subscription) {
    console.log('User is subscribed.');
    isSubscribed = true;
  .catch(function(err) {
    console.log('Failed to subscribe the user: ', err);
Routine to send push notification: ~/server/routes.js:25

const pushOptions = {
        vapidDetails: {
          subject: 'mailto:' + vapidKeys.EMAIL,
          publicKey: vapidKeys.PUBLIC_KEY,
          privateKey: vapidKeys.PRIVATE_KEY

Show the user the notification message - ~/public/sw.js:38

// Copied from
self.addEventListener('push', event => {
  let thisMessage =
    console.log("We got this message: " + thisMessage)
    console.log('[Service Worker] Push Received.');
    console.log(`[Service Worker] Push had this data: "${}"`);

    const title = 'PWA';
    const options = {
      body: thisMessage,
      // We didn't implement these pieces
      icon: 'images/icon.png',
      badge: 'images/badge.png'

    event.waitUntil(self.registration.showNotification(title, options));