The State of the Union

Maxim Salnikov

Angular GDE

Angular + PWA

Maxim Salnikov

  • Google Developer Expert in Angular

  • Angular Oslo / PWA Oslo meetups organizer

  • ngVikings conference organizer

Products from the future

UI Engineer at ForgeRock

ngVikings.org

  • All sides of Angular ecosystem

  • 100% community-driven event from developers for developers

  • True Nordics spirit and Vikings power

Follow Twitter

March 1-2, Helsinki, Finland

Milestones of the web

AJAX

Static

Dynamic

RWD

PWA

Progressive Web App

... attempts to combine features offered by most modern browsers with the benefits of mobile experience

... web apps that use the latest web technologies.

10 characteristics

  • Progressive
  • Discoverable
  • Linkable
  • App-like
  • Responsive
  • Connectivity-independent
  • Re-engageable
  • Installable
  • Fresh
  • Safe

 App Shell architecture

 Service Worker API

Push API and Notifications API

Involved APIs

  • Service Worker API

  • Cache API

  • Fetch API

  • Notifications API

  • Push API

  • IndexedDB API

  • Promises

Create Angular Progressive Web App

  • Code service worker manually

  • Go for some PWA libraries

  • Use Angular Service Worker

sw-precache

2   packages

@angular/service-worker

v1.0.0-beta.16 - Experimental service worker by the Angular Mobile team

@angular/app-shell

v0.1.0 - App Shell runtime library for Angular Progressive Web Apps

Service Worker

Angular Service Worker

NGSW

NGSW installation

# First, install the Angular Service Worker
$ npm install --save @angular/service-worker
# Enable the SW registration + app shell in Angular CLI
$ ng set apps.0.serviceWorker=true
"apps": [
    {
        "serviceWorker": true
    }
]

.angular-cli.json

App build

# NGSW works only in --prod mode
$ ng build --prod
<script src="sw-register.{HASH}.bundle.js"></script>
  • sw-register.{HASH}.bundle.js

  • worker-basic.min.js

  • ngsw-manifest.json

index.html

Static content caching

{
  "static": {
    "urls": {
      "/index.html": "ae543...",
      "/main.bundle.js": "9ff18...",
      "/styles.bundle.css": "d6f44...",
      "/assets/images/logo.png": "0e33a...",
      ...
    }
  }
}

ngsw-manifest.json

Angular PWA

Static Content

Cache

Route redirection

{
  "routing": {
    "index": "/index.html",
    "routes": {
      "/": {
        "match": "exact"
      },
      "/some/routes-group-prefix": {
        "match": "prefix"
      }
    }
  }
}

ngsw-manifest.json

Extending NGSW manifest

{
    "static" : {
        ...autogenerated
    }
}
{
    "routing" : {...}
    ...
}

ngsw-manifest.json

External content caching

{
  "external": {
    "urls": [
      {
        "url": "https://fonts.gstatic.com/Roboto.ttf"
      }
    ]
  }
}

ngsw-manifest.json

Angular PWA

Static Content

Cache

External Content Cache

Dynamic content caching

{
  "dynamic": {
    "groups": [
      {
        "name": "api",
        "urls": {...},
        "cache": {...}
       }
    ]
  }
}

ngsw-manifest.json

Dynamic cache settings

cache: {
  "optimizeFor": "freshness",   // or 'performance'
  "networkTimeoutMs": 200,
  "maxAgeMs": 1000,
  "maxEntries": 2,
  "strategy": "fifo"            // or 'lru', 'lfu'
}
urls: {
    "/api/breakingnews": {
        "match": "prefix"
    }
},

ngsw-manifest.json

Angular PWA

Static Content

Cache

External Content Cache

Dynamic Content

Cache

Push notifications

Backend

Notification

Push Service

NGSW

App

Backend

Push Service

App

Subscription

Sending a notification

Push settings

{
  "push": {
    "showNotifications": true
  }
}

ngsw-manifest.json

Companion

import {NgServiceWorker} from '@angular/service-worker';
constructor(public sw: NgServiceWorker) {}

app.component.ts

import {ServiceWorkerModule} from '@angular/service-worker'
imports: [
    ...
    ServiceWorkerModule
]

app.module.ts

Push subscription

constructor(public sw: NgServiceWorker) {}
sw
    .registerForPush({
        applicationServerkey: 'H7nef93Mds....'
    })
    .subscribe(subscriptionObject => {
        // Send subscription data to the server
    });
import {NgServiceWorker} from '@angular/service-worker';

push.component.ts

Push subscription

push.component.ts

sw.push.subscribe(notificationPayload => {
    // Process notification data
});

Angular PWA

Static Content

Cache

External Content Cache

Push

Dynamic Content

Cache

Automatic PWA

{
  "static": {...},
  "routing": {...},
  "external": {...},
  "dynamic": {...},
  "push": {...}
}

ngsw-manifest.json

Angular PWA

Static Content

Cache

External Content Cache

Push

Dynamic Content

Cache

Automatically

Roadmap

  • Move Angular Service Worker to Angular Core

  • More tight integration with Angular CLI

  • Simplify server-side rendering flow

  • Make Progressive Angular Apps very common!

 

Documentation!

¡Muchas gracias!

@webmaxru

Maxim Salnikov

Questions?

Automatic Progressive Web Apps using Angular Service Worker

By Maxim Salnikov

Automatic Progressive Web Apps using Angular Service Worker

Progressive Web Apps are the next big thing for the web. They combine the advantages of two platforms: searchability and shareability of the web with capabilities and performance of native mobile. As a result, web developers can use their favorite tools to build installable, re-engageable, connectivity independent apps, that can bring native-like performance and user experience.

  • 2,219