Angular PWA

Make Angular App great again

Angular PWA: Make Angular App great again

byMeetup #1

About me:

Babrouskaya Iryna

History

Steve Jobs 2007

2007

Steve Jobs announced new web apps developed in HTML5 and AJAX

  1. 2010: Web Workers
  2. 2015: new term "Progressive Web Applications", started developing PWA for Android
  3. 2017: Apple supports Service Workers
  4. 2017: Angular Service Worker
  5. 2018: Angular PWA
  6. 2019: PWA everywhere*

* almost everywhere

Progressive Web Applications

Progressive

Responsive

Connectivity independent

App-like

Fresh

Safe

Discoverable

Re-engageable

Installable

Linkable

Progressive Web Applications is:

  1. Progressive
  2. Responsive
  3. Connectivity independent
  4. App-like
  5. Fresh
  1. Safe
  2. Discoverable
  3. Re-engageable
  4. Installable
  5. Linkable

Where can be installed

PWA Bugs (August, 2019)

PWA Bugs (August, 2019)

Screenshot from GitHub repository PWA-POLICE

Angular logo

+? =

pwa logo

Service Workers

Service Workers CAN

  1. At least provide caching
  2. Background data synchronization
  3. Push Notifications
  4. Performance enhancement (for example, pre-loading content)

Cashing strategies

Network or Cache Network or Cache

Cashing strategies

Cache only Cache only

Cashing strategies

Cache and update Cache and update

Cashing strategies

Cache and update and refresh Cache and update and refresh

Cashing strategies

Cache and update and refresh Cache and update and refresh

Cashing strategies

Embedded fallback Embedded fallback

Service Workers CAN'T

  1. Access the Window Object, DOM
  2. Working over HTTP (except localhost)
  3. Use synchronous APIs like XHR or localStorage

Angular PWA

Example (no PWA)

Using @angular/pwa and NGSW

            ng add @angular/pwa
        

ng add @angular/pwa

Generated App Manifest

        
{
  "name": "my-perfect-pwa",
  "short_name": "my-perfect-pwa",
  "theme_color": "#1976d2",
  "background_color": "#fafafa",
  "display": "standalone",
  "scope": "/",
  "start_url": "",
  "icons": [
    {
      "src": "assets/icons/icon-72x72.png",
      "sizes": "72x72",
      "type": "image/png"
    },
    {
      "src": "assets/icons/icon-96x96.png",
      "sizes": "96x96",
      "type": "image/png"
    },
    {
      "src": "assets/icons/icon-128x128.png",
      "sizes": "128x128",
      "type": "image/png"
    },
    {
      "src": "assets/icons/icon-144x144.png",
      "sizes": "144x144",
      "type": "image/png"
    },
    {
      "src": "assets/icons/icon-152x152.png",
      "sizes": "152x152",
      "type": "image/png"
    },
    {
      "src": "assets/icons/icon-192x192.png",
      "sizes": "192x192",
      "type": "image/png"
    },
    {
      "src": "assets/icons/icon-384x384.png",
      "sizes": "384x384",
      "type": "image/png"
    },
    {
      "src": "assets/icons/icon-512x512.png",
      "sizes": "512x512",
      "type": "image/png"
    }
  ]
}
        
    

Angular app to PWA: first step

App is available in the offline mode

Make app installable - add simple code to your component

        
$event = fromEvent(window, 'beforeinstallprompt');
$event.subscribe((promptEvent) => {}));
        
    
Default prompt

Make app installable

        
$event = fromEvent(window, 'beforeinstallprompt');
$event.subscribe((event) => {
     event.preventDefault();
     showCustomPrompt();
));
        
    
Custom prompt

Let's cache: ngsw-config

        
{
  "$schema": "./node_modules/@angular/service-worker/config/schema.json",
  "index": "/index.html",
  "assetGroups": [
    {
      "name": "app",
      "installMode": "prefetch",
      "resources": {
        "files": [
          "/favicon.ico",
          "/index.html",
          "/*.css",
          "/*.js"
        ]
      }
    }, {
      "name": "assets",
      "installMode": "lazy",
      "updateMode": "prefetch",
      "resources": {
        "files": [
          "/assets/**",
          "/*.(eot|svg|cur|jpg|png|webp|gif|otf|ttf|woff|woff2|ani)"
        ]
      }
    }
  ]
}

        
    

Cache resources

Notify user about update in your component

import { SwUpdate } from '@angular/service-worker';
        constructor(private swUpdate: SwUpdate) {
          swUpdate.available.subscribe(event => {
              if (askUserToUpdate()) {
                  window.location.reload();
              }
          });
        }
    

Notifications

Notifications

        
self.addEventListener('push', function (event) {
  const data = event.data.json();
  const title = data.title;
  const options = {body: data.body,
            icon: 'icons/icon-72x72.png',data: data.click_action};
  const promiseChain = self.registration
            .showNotification(title, options);
  promiseChain.then(function(subscription) {});
  event.waitUntil(promiseChain);
});
        
    

Demo

Demo

Should I develop PWA?

YES*

AliExpress results

  • 104% for new users across all browsers; 82% increase in iOS conversion rate
  • 2X more pages visited per session per user across all browsers
  • 74% increase in time spent per session across all browsers
Aliexpress
Read more about Aliexpress case

Alternatives

How to add Workbox to Angular project

The end

Angular heart

Questions?

Useful links

Useful links