Skip to content

14 PWA

Progressive Web Apps

Regular websites, enhanced to work in mobile phones.

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

Main components

Uses modern web technologies – https, manifest, service workers, html5

Manifest – describes to the system how to make Native-like app out of website

Service Worker is a script that works on browser background without user interaction independently. Also, it resembles a proxy that works on the user side. With this script, you can track network traffic of the page, manage push notifications and develop "offline first" web applications with Cache API.

Everything is bleeding edge, iOS has support since March 2018. (iOS 11.3)

Why

native

Twitter Lite

native native native

Manifest

Filename: manifest.webmanifest

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
{
  "name": "Hacker Web",
  "short_name": "HackerWeb",
  "start_url": "/",
  "display": "standalone",
  "background_color": "#fff",
  "description": "A simple app.",
  "icons": [{
    "src": "images/touch/homescreen48.png",
    "sizes": "48x48",
    "type": "image/png"
  }]
}

Manifest - display

  • Display: browser, minimal-ui, standalone, full screen
  • Fullscreen
    All of the available display area is used, and no user agent chrome is shown.
  • Standalone
    The application will look and feel like a standalone application. This can include the application having a different window, its own icon in the application launcher, etc. In this mode, the user agent will exclude UI elements for controlling navigation but can include other UI elements such as a status bar.
  • Minimal-ui
    The application will look and feel like a standalone application but will have a minimal set of UI elements for controlling navigation. The elements will vary by browser.
  • Browser
    The application opens in a conventional browser tab or new window, depending on the browser and platform. This is the default.

Manifest - icons

Icons

Specifies an array of objects representing image files that can serve as application icons for different contexts. For example, they can be used to represent the web application amongst a list of other applications, or to integrate the web application with an OS's task switcher and/or system preferences. Splash screen on launch.

Manifest - orientation

Orientation

  • any
  • natural
  • landscape
  • landscape-primary
  • landscape-secondary
  • portrait
  • portrait-primary
  • portrait-secondary

https://www.w3.org/TR/screen-orientation/#dfn-screen-orientation-values-table

Manifest - color

background_color, theme_color

  • The background_color member defines a placeholder background color for the application page to display before its stylesheet is loaded. This value is used by the user agent to draw the background color of a shortcut when the manifest is available before the stylesheet has loaded.

  • The theme_color member is a string that defines the default theme color for the application. This sometimes affects how the OS displays the site (e.g., on Android's task switcher, the theme color surrounds the site).

Manifest - headers

Some parts are still experimental, iOS need some stuff in html headers also.

1
2
3
<link rel="icon" sizes="192x192" href="/img/icon-192x192.png">
<link rel="apple-touch-icon" href="/img/icon-192x192.png">
<link href="/manifest.webmanifest" rel="manifest" />

Service Workers 1

A service worker is a script that your browser runs in the background, separate from a web page (no DOM access, no user interaction)

  • Background sync,
  • Caching,
  • Push notifications,
  • Offline experience (network proxy)
  • Terminated automatically – if you need state, then store it in DB

Extensive use of native promises!

Promises

https://courses.taltech.akaver.com/javascript/lectures/09-promises/

Service Workers 2

  • Service Worker is a script that works on browser background without user interaction independently.
  • Resembles a proxy that works on the user side.
  • With this script, you can track network traffic of the page.
  • And manage push notifications
  • Develop "offline first" web applications with Cache API.
  • Background sync!

PWA architecture

50 mile overview

native

PWA lifecycle on install

Typical lifecycle on first installation

native

PWA lifecycle detailed

native

PWA lifecycle register

  • A service worker has a lifecycle that is completely separate from web page.
  • Registering a service worker will cause the browser to start the service worker install step in the background – typically done in /index.html (head or end of body). Service worker is scoped by its location - so use root dir.
1
2
3
4
5
6
<script>
if ('serviceWorker' in navigator) {
    navigator.serviceWorker.register('/sw.js')
        .then(function () { console.log("Service worker registered"); });
}
</script>

PWA lifecycle install

First event to run, when app gets installed. Prefetch resources needed for app launch.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
var CACHE = 'cache_0.0.1';

self.addEventListener('install', function (event) {
    var urlsToPrefetch = [
        './static/pre_fetched.txt', './static/pre_fetched.html',
    ];
    console.log('Install. Pre-fetch:', urlsToPrefetch);
    event.waitUntil(
        caches.open(CACHE).then(function (cache) {
            cache.addAll(urlsToPrefetch.map(function (urlToPrefetch) {
                return new Request(urlToPrefetch, { mode: 'no-cors' });
            })).then(function () {
                console.log('All done.’);
            });
        }).catch(function (error) {
            console.error('Pre-fetching failed:', error);
        })
    );
});

PWA lifecycle activate

  • This is a generally used to do stuff that would have broken the previous version while it was still running, for example getting rid of old caches.
  • This is also useful for removing data that is no longer needed to avoid filling up too much disk space — each browser has a hard limit on the amount of cache storage that a given service worker can use.

Delete everything from cache that is not current

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
self.addEventListener('activate', (event) => {
    event.waitUntil(
        caches.keys().then((keyList) => {
            return Promise.all([CACHE].map((key) => {
                if (cacheKeeplist.indexOf(key) === -1) {
                    return caches.delete(key);
                }
            }));
        })
    );
});

PWA lifecycle fetch

Proxy all the app network requests. Decide what to do on case of hit, miss, offline, etc.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
self.addEventListener('fetch', (event) => {
    event.respondWith(
        caches.match(event.request).then((resp) => {
            return resp || fetch(event.request).then((response) => {
                return caches.open(CACHE).then((cache) => {
                    cache.put(event.request, response.clone());
                    return response;
                });
            });
        })
    );
});

Resources

  • https://jakearchibald.github.io/isserviceworkerready/resources.html
  • https://developers.google.com/web/fundamentals/primers/service-workers
  • https://dev.to/voodu/vue-3-pwa-service-worker-12di
  • https://www.vuemastery.com/blog/getting-started-with-pwas-and-vue3/
  • https://developers.google.com/web/tools/workbox
  • https://deanhume.com/displaying-a-new-version-available-progressive-web-app/
  • https://www.udemy.com/course/progressive-web-app-pwa-the-complete-guide/