Aliaksei Kuncevič

Software Engineer/Angular Consultant

PWA with Angular

by Aliaksei Kuncevič

What is

Progressive web apps (PWAs) are web applications that are regular web pages or websites, but can appear to the user like traditional applications or native mobile applications. The application type attempts to combine features offered by most modern browsers with the benefits of mobile experience.

(c) Wikipedia

modern browser features

what web can do

The PWA King




A service worker is an event-driven worker registered against an origin and a path. It takes the form of a JavaScript file that can control the web page/site it is associated with, intercepting and modifying navigation and resource requests, and caching resources in a very granular fashion to give you complete control over how your app behaves in certain situations.

Service workers essentially act as proxy servers that sit between web applications, the browser, and the network (when available).

(c) Mozilla

Service Worker

Use Cases

  • Caching app bundles, assets and api calls
  • Background data sync/preload/offline
  • Push Notifications

Browsers Support

PWA experiences

  • Reliable (load instantly)
  • Engaging (feel like a natural app)
  • Fast (respond quickly to user interactions)


Cache, network state


Installable, user home screen, push notifications


53% of users will abandon a site if it takes longer than 3 seconds to load



Angular PWA

Developer experience

  • No need to implement service worker yourself
  • Angular-aware service worker
  • Config-driven
  • Refreshing in all opened browser tabs

Angular cli


  • PWA Support (CLI v.1.6+)
  • Scaffolding (minimize boilerplate)
  • Run unit and e2e tests
  • Linting (tslint, codelyzer)
  • Transpiling TypeScript
  • Compress assets
  • Compiling LESS/SASS
  • Webpack (dev, prod builds, code split)
  • Threes Shaking
  • Build Optimizeration/Minification
  • Produce CSS and JS bundles

how to start

npm install -g @angular/cli
ng new my-app --service-worker
cd my-app
ng build --prod
ng add pwa //coming soon

build output

Code example

import { SwPush } from '@angular/service-worker';

  selector: 'app-control-push',
  templateUrl: './control-push.component.html',
  styleUrls: ['./control-push.component.css']
export class ControlPushComponent {
  constructor(private swPush: SwPush) { }

  showMessages() {
      .subscribe(message => {
        console.log('[App] Push message received', message);


  "index": "/index.html",
  "appData": {
    "name": "app v1",
    "description": "sample app"
  "assetGroups": [{
    "name": "app",
    "installMode": "prefetch",
    "resources": {
      "files": [
      "versionedFiles": [
  }, {
    "name": "assets",
    "installMode": "lazy",
    "updateMode": "prefetch",
    "resources": {
      "files": [
  }, {
    "name": "fonts",
    "resources": {
      "urls": [
  "dataGroups": [{
      "name": "api-timeline",
      "urls": [
      "cacheConfig": {
        "strategy": "freshness",
        "maxSize": 100,
        "maxAge": "2d",
        "timeout": "10s"
      "name": "api-history",
      "urls": [
      "cacheConfig": {
        "strategy": "performance",
        "maxSize": 100,
        "maxAge": "5d"


  • http://localhost:[your-port]/ngsw/state

debug info


Lighthouse Report

Hacker News readers as Progressive Web Apps



  • ng set apps.0.serviceWorker=false
  • Make sure server respond with 404 for ngsw.json

fetch manifest

async fetchLatestManifest() {
  const res = await this.safeFetch(
    this.adapter.newRequest('ngsw.json?ngsw-cache-bust=' + Math.random())
  if (!res.ok) {
    if (res.status === 404) {
      await this.deleteAllCaches();
    throw new Error('Manifest fetch failed!');
  this.lastUpdateCheck = this.adapter.time;
  return res.json();

ngsw code


questions ?