Workbox

Maxim Salnikov

Angular GDE

Building an Angular PWA:

NGSW

?

?

?

- or -

+ what's new in PWA

Maxim Salnikov

  • Google Developer Expert in Angular

  • Angular Oslo / PWA Oslo meetups organizer

  • ngVikings /  ngCommunity organizer

  • Leading webdev track at 404fest.ru (Samara, September 14-15)

Azure Developer Technical 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

UX advantages?

Smart networking + Offline

Proper app experience

Staying notified

Other cool things

}

Service Worker API

Web App Manifest

Almost 100 new APIs

Badging API

Contact Picker API

Native File System API

Periodic Background Sync API

  • NOT a "cron" in a browser

  • Works only when online

  • The browser is a decision maker

Installation

Anything else we need?

Create Angular PWA

  • Code service worker manually

  • Use Angular Service Worker (NGSW)

  • Use some PWA libraries

Minimum viable PWA

=

+

Application shell

Web App Manifest

Fast, responsive, mobile-first

Served via HTTPS

Logically

Physically

-file(s)

App

Service-worker

Browser/OS

Event-driven worker

Cache

fetch
push
sync

Managing cache

self.addEventListener('install', (event) => {
  
    // Put app's html/js/css to cache

})
self.addEventListener('activate', (event) => {
  
    // Wipe previous version of app files from cache

})

In the real world

  • Can't add opaque responses directly

  • Redirected requests should be managed

  • Always creating a new version of cache and deleting the old one is not optimal

  • Control over cache size is required

  • Cache invalidation for runtime caching is complex

  • ...

Intercepting requests

self.addEventListener('fetch', (event) => {

  if (event.request.url.indexOf('/api') != -1) {
    event.respondWith(
      // Network-First Strategy
    )
  } else {
    event.respondWith(
      // Cache-First Strategy
    )
  }
})

In the real world

  • All kinds of fallbacks needed for the strategies

  • There are more complex strategies like Stale-While-Revalidate

  • Good to have routing

  • Good to have the possibility to provide some extra settings for different resource groups

  • ...

Pros

  • Great flexibility!

 

Cons

  • Great responsibility!

 

  • Implementing complex algorithms

  • Adopting best practices

  • Focusing on YOUR task

  • Following specifications updates

  • Handling edge cases

Tools help with

NGSW

Angular Service Worker

NGSW

Automation

Scaffolding

Building

Serving

Schematics

Angular CLI

NGSW

$ ng add @angular/pwa

Scaffold

$ ng build --prod

Build

$ ng serve

Serve

ngsw-config.json

src/manifest.webmanifest

Updated

What's happened?

Built

ngsw.json

ngsw-worker.js

src/assets/icons/icon-*.png

Scaffolded

src/index.html

src/app/app.module.ts

ngsw-config.json / assetGroups

{
    "name": "app",
    "installMode": "prefetch",
    "resources":







}
    "resources": {    
        "files": [
            "/favicon.ico",
            "/index.html",
            "/*.css",
            "/*.js"
        ]
    }

Configuration file

  • Application shell

  • Runtime caching

  • Replaying failed network requests

  • Offline Google Analytics

  • Broadcasting updates

Have our own service worker!

Working modes

  • Workbox CLI

  • Webpack plugin

  • Node module

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

Build script

// 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-inject.js

Build script configuration

// Sample configuration with the basic options
var workboxConfig = {
  globDirectory: 'dist/angular-pwa/',
  globPatterns: [
    '**/*.{txt,png,ico,html,js,json,css}'
  ],
  swSrc: 'src/service-worker.js',
  swDest: 'dist/angular-pwa/service-worker.js'
}

workbox-build-inject.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/service-worker.js

Workbox manifest

[
  {
    "url": "index.html",
    "revision": "34c45cdf166d266929f6b532a8e3869e"
  },
  {
    "url": "favicon.ico",
    "revision": "b9aa7c338693424aae99599bec875b5f"
  },
  ...
]

Build flow integration

{
  "scripts": {
    "build-prod": "ng build --prod &&
                   node workbox-build-inject.js"
  }
}

package.json

NGSW

  • Convenient build module

  • Having our own service worker and extending it by Workbox modules

  • One-liner to start

  • Seamless integration

  • Smart defaults

Other features?

NGSW

Events to inform about app shell updates

Runtime caching based on the strategies

Push notifications helpers

Web App Manifest

Extendable

Summary

NGSW

  • Easy to start

  • Seamless integration with Angular

  • Coding-free basic features

  • Angular-friendly approach

Add -> Configure

Get what's included

  • Framework-agnostic

  • Rich functionality

  • Maximum flexible configuration

  • Full power of our own service worker

Setup -> Configure -> Code

Get what you want

  • 2000+ developers

  • Representatives from the browsers, frameworks, libraries

  • Все о PWA на русском языке

Thank you!

Maxim Salnikov

@webmaxru

Questions?

Maxim Salnikov

@webmaxru