One PWA Solution

Maxim Salnikov

@webmaxru

Many Frameworks

How to build a framework-agnostic PWA?

Using the power of your favorite framework

Maxim Salnikov

  • PWAdvocate

  • PWA Oslo / PWA London meetups organizer

  • ngVikings and Mobile Era conferences organizer

  • Google Dev Expert in Web Technologies

Azure Developer Relations Lead at Microsoft

What is PWA at all?

Progressive web apps use modern web APIs along with traditional progressive enhancement strategy to create cross-platform web applications.

These apps work everywhere and provide several features that give them the same user experience advantages as native apps.

works everywhere*

* but not everything**

natively

** use progressive enhancement strategy

What do frameworks give us?

=

+

Application shell

Web App Manifest

Fast, responsive, mobile-first

Served via HTTPS

The most popular frameworks

React

SW library

Out-of-the-box

Configuring

Extending

Workbox

Web App Manifest

App Shell

$ create-react-app my-react-pwa
serviceWorker.unregister();
serviceWorker.register();

Vue

SW library

Out-of-the-box

Configuring

Extending

Workbox

Web App Manifest

App Shell

Runtime Caching

$ vue add pwa

Angular

SW library

Out-of-the-box

Configuring

Extending

Angular

Service Worker

Web App Manifest

App Shell

Runtime Caching

Push Notifications

Update Flow

$ ng add @angular/pwa

Built-in PWA support

Pros

Cons

  • Seamless integration

  • Easy to start

  • Limited configuration options

  • Difficult to impossible to extend

  • Challenging to add to the existing app

How many frameworks do we use

Requirements

  • Automation of the main service worker tasks

  • Framework-agnostic

  • CI/CD-friendly

  • Full control and flexibility

  • Extensibility

Let's build an App shell

My App

  • Define assets

  • Put in the cache

  • Serve from the cache

  • Manage versions

}

Service worker

Logically

Physically

-file(s)

App

Service worker

Browser/OS

Event-driven worker

Cache

fetch
push
sync

Own service worker

self.addEventListener('install', event => {
    // Use Cache API to cache html/js/css
})

self.addEventListener('activate', event => {
    // Clean the cache from the obsolete versions
})

self.addEventListener('fetch', event => {
    // Serve assets from cache or network
})

handmade-service-worker.js

It's only partially a joke

Because...

Redirects?

Fallbacks?

Opaque response?

Versioning?

Cache invalidation?

Spec updates?

Cache storage space?

Variable asset names?

Feature detection?

Minimal required cache update?

Caching strategies?

Routing?

Fine-grained settings?

Kill switch?

I see the old version!!!

  • Application shell

  • Runtime caching

  • Replaying failed network requests

  • Offline Google Analytics

  • Broadcasting updates

While having our own service worker

Working modes

  • Workbox CLI

  • Webpack plugin

  • Node module

# Installing the Workbox Node module
$ npm install workbox-build --save-dev

Configuration

...
var workboxConfig = {
  globDirectory: 'dist/',
  globPatterns: [
    '**/*.{txt,png,ico,html,js,json,css}'
  ],
  swSrc: 'src/workbox-service-worker.js',
  swDest: 'dist/sw.js'
}
...

workbox-build.js

Source service worker

// Importing Workbox itself from Google CDN
importScripts('https://googleapis.com/.../workbox-sw.js');

// Precaching and setting up the routing
workbox.precaching.precacheAndRoute([])

src/workbox-service-worker.js

Caching, serving, managing versions

Build service worker

// We will use injectManifest mode
const {injectManifest} = require('workbox-build')

// Sample configuration with the basic options
var workboxConfig = {...}

// Calling the method and output the result
injectManifest(workboxConfig).then(({count, size}) => {
    console.log(`Generated ${workboxConfig.swDest},
    which will precache ${count} files, ${size} bytes.`)
})

workbox-build.js

Build flow integration

{
  "scripts": {
    "build-pwa": "npm run build-app &&
                  node workbox-build.js"
  }
}

package.json

App build files

App shell file list

Service worker file

Service worker can do more!

// App shell
workbox.precaching.precacheAndRoute([])

// Runtime caching
workbox.routing.registerRoute(
  /(http[s]?:\/\/)?([^\/\s]+\/)api/,
  workbox.strategies.networkFirst()
)

// Push notifications
self.addEventListener('push', (event) => {...})

src/workbox-service-worker.js

if ('serviceWorker' in navigator) {
    navigator.serviceWorker
        .register('/service-worker.js')
}

Service worker registration

Requirements

  • Feature detection

  • Registration after app fully loaded and UI rendered

  • Hook into service worker update event

There is a new version of the app is available. Click here to refresh.

  • Was the service worker updated?

  • Was the app itself updated?

Using workbox-window

import { Workbox } from 'workbox-window'
// For Angular
platformBrowserDynamic().bootstrapModule(AppModule)
  .then( () => {
    if ('serviceWorker' in navigator) {
      const wb = new Workbox('service-worker.js');
      // Event listeners...
      wb.register();
    }
  })

main.js

$ npm install workbox-window

Was service worker file updated?

wb.addEventListener('installed', event => {
  if (event.isUpdate) {
  // Show "Newer version is available. Refresh?" prompt
  } else {
  // Optionally: show "The app is offline-ready" toast
  }
});

main.js

workbox.core.skipWaiting()
workbox.core.clientsClaim()

src/workbox-service-worker.js

Must have!

Summary

  • PWA idea moves Web Platform forward

  • Popular frameworks embrace it and have official plugins

  • Creating your own service worker might be tricky

  • But extending it by Workbox functionality could be a good option

Try it today!

  • 2000+ developers

  • Major browsers/frameworks/libs reps

Thank you!

Maxim Salnikov

@webmaxru

Questions?

Many frameworks - one PWA solution

By Maxim Salnikov

Many frameworks - one PWA solution

There is no doubt that 2018 is the year when Progressive Web Apps will get the really broad adoption and recognition by all the involved parties: browser vendors (finally, all the major ones), developers, users. How does PWA concept play with YOUR favorite framework? React, Angular, Vue, #FrameworkOfTheWeek? In my technical session we’ll check what major frameworks creators prepared for us regarding scaffolding / adding PWA features (spoiler: only basic features), and switch to Workbox. We’ll see that Workbox is a library providing many sophisticated service worker features in a simple, developer-friendly form. Also, we’ll talk about another advantage of Workbox - the flexibility: you build your own service worker and automate some tasks using this library. As the outcome, you’ll be ready to make a production-ready PWA from the app built on any framework.

  • 3,317