The Web for all. The power of Progressive Web Apps.

Staff Developer Advocate at 

Patricio Vargas (Pato)

  • Google Developer Expert on Web Technologies
  • Microsoft MVP
  • Auth0 Ambassador
  • AWS Community Builder
  • Postman Supernova
  • Twilio Champion
  • Media Developer Expert at Cloudinary
  • Women Techmaker

@devpato

What is a PWA?

@devpato

What is a PWA?

A PWA stands for Progressive Web Applications. PWAs are web apps that have the ability to be installed on your phone as a native app.

 

@devpato

Who uses PWA?

@devpato

What are the superpowers of a PWA?

PWA Superpowers

  • Instalability
  • SEO Friendly
  • Push Notifications
  • Performance
  • User Experience
  • Offline Experience
  • Payments: PayPal, Apple Pay, Google Pay, etc
  • Multiplatform

@devpato

What are the disadvantages of PWA

Disadvantages of PWA

  • Caching Can Be Dangerous
  • Less Access To System Features
  • No Review Standard
  • Apple Needs to catchup with the technology

@devpato

Why did I fall in love with PWA?

 

My Story with PWA

  • PWA is in more than 120 countries
  • 1/5 Americans have products of our client
  • Reduced the number of server calls by 32%
  • Increased users by millions
  • Improved UX
  • Products were easier to be found on the web
  • PWA load time was ~3 sec
  • By 2019, the client was earning $8.8B 

@devpato

Main Components
Of A PWA

 

 

PWA Components

  • Web Applications
  • Manifest.json
  • Service Worker (sw.js, serviceWorker.js)

@devpato

Web Applications

@devpato

Manifest.json

The manifest.json is a simple JSON file on your website that tells the browser about your website on the user's desktop or mobile device. The browser requires a manifest to display the Add to Home Screen message or icon.

@devpato

Service Worker

A Service worker is a proxy script between your web app and the outside. Service Workers execute separately from the main browser thread.

Web App

Service Worker

Cache

Network

@devpato

What are the superpowers of a
Service Worker?

Service Worker superpowers 

  • Network requests.
  • Handle how network requests are done on your website.
  • Make use of the Background Sync API.
  • Cache things from your website.
  • Receive push notifications when the app is not active.
  • Stay inactive when it's not in use.
  • Used to make your app work offline.
  • Display an offline page in case of connection failure.
  • Capture offline metrics.
  • Perform load balancing in the client side.

@devpato

PRE-CACHE

VS

RUNTIME CACHE

@devpato

Pre-Cache

Your resources are put in the cache before they are requested.

E.g Your web app start URL, offline fallback, and, key js and files

 

Pre-caching happens at the service worker install event at the cache first strategy

 

@devpato

Runtime Cache

Runtime cache adds resources to the cache when they are requested.  Runtime caching works with different caching strategies and the resources are cached independently.

 

E.g a new cache named "images".

 

 

 

@devpato

Service Worker Lifecycles

index.js

sw.js

@devpato

Registering the Service Worker

if ("serviceWorker" in navigator) {
    window.addEventListener("load", ()=>{
        navigator.serviceWorker.register("sw.js").then(swRegistered => {
            console.log("[ServiceWorker**] - Registered");
        });
    });
}

index.js

@devpato

Installing the Service Worker

const cacheName = "my-pwa-shell-v1.0";
const filesToCache = [
    "index.html",
    "./js/index.js",
    "./styles/styles.css",
    "manifest.json",
    "./assets/icons/icon.png",
    "./assets/nike1.jpeg",
];


self.addEventListener("install", e => {
    console.log("[ServiceWorker] - Install");
    e.waitUntil((async () => {
		const cache = await caches.open(cacheName);
		console.log("[ServiceWorker] - Caching app shell");
		await cache.addAll(filesToCache);
    })());
});

sw.js

@devpato

Activating Service Worker

self.addEventListener("activate", e => {
    e.waitUntil((async () => {
        const cacheList = await caches.keys();
        await Promise.all(
            cacheList.map(currentCache => {
            	// currentCache = "cacheVersion-1.0" , newCache = "cacheVersion-2.0"
                if (currentCache !== newCache) { 
                    return caches.delete(currentCache);
                }
            })
        );
    })());
});

sw.js

@devpato

Fetching
(Intercepting Network Call)

self.addEventListener('fetch', e => {
    e.respondWith((async () => {
        const resource = await caches.match(e.request);
        
        return resource || fetch(e.request);
    })());
});

sw.js

@devpato

DEMO

@devpato

Resources

@devpato

Made with Slides.com