PWA

Crash Course

My name is Rafael Fernandes and that's my face.

AdamModus

@AdamModus

https://adammode.xyz

Sup?

Amsterdam

Lisbon

About me

That's me!

Rabobank

About me

Agenda

  • PWA? WTF?
  • PWA main points
  • Philosophy time
  • Web App Manifest
  • Service Worker FTW
    • Life cycle
    • Gotchas
    • Extras
  • P is for Performance!
  • Client side storage
  • Q&A

PWA? WTF?

  • Progressive - Works for every user, regardless of browser choice
  • Responsive - Fits any form factor! 📱 / 💻 / 📺 / etc...
  • Reliable - Enhanced with service workers to work on uncertain network conditions
  • App-like - Feels like a native app, with an immersive user experience
  • Fresh - Always up-to-date thanks to the service worker update process
  • Safe - Served only via HTTPS to ensure user's privacy and communication safety
  • Discoverable - Is identifiable as an "application" thanks to W3C manifest and service worker registration scope, allowing search engines to find it
  • Re-engageable - Makes re-engagement easy through features like push notifications
  • Installable - Allows users to add PWAs to their home screen
  • Linkable - Easily shared via URL, does not require complex installation
  • Fast - Respond quickly to user interactions smoothly and with no janky scrolling.

PWA? WTF?

Technology behind PWAs:

  • Service Workers - It enables asset caching and background tasks
  • IndexedDB - A database in the browser
  • LocalStorage - A place to store small amounts of data in the browser
  • Mobile sensors API - Interface hardware directly: touch, mic, camera, motions, vibration, location, etc...
  • Web App Manifest - To add the PWA to the home screen and provide some more immersive experience
  • Web workers - Multi-threading possibilities

Philosophy time!

Philosophy time!

The worst we can do to the user is give him nothing!

Philosophy time!

  • Cached your assets, even in real time
  • Cached information is better than nothing, users are happier in all scenarios: Online / Offline / Li-fi
  • Think about multiple form factors
  • Accessibility is very relevant
  • Check your performance measures

 

We're here for our users so ultimately we should focus on user experience!

Offline first philosophy:

Web App Manifest

{
  "short_name": "Offline survivor",
  "name": "Surviving the offline status",
  "description": "An example PWA",
  "background-color": "#FAFAFA",
  "icons": [
    {
      "src": "imgs/icon/favicon-96x96.png",
      "sizes": "96x96",
      "type": "image/png"
    },
    {
      "src": "imgs/icon/favicon-144x144.png",
      "sizes": "144x144",
      "type": "image/png"
    },
    {
      "src": "imgs/icon/favicon-196x196.png",
      "sizes": "196x196",
      "type": "image/png"
    }
  ],
  "start_url": "/index.html",
  "display": "standalone"
}
<link rel="manifest" href="manifest.json">

Service Worker FTW

web page

server

Service Worker FTW

SW.js

web page

server

Cache storage (sw cache)

SW.js

web page

server

Cache storage (sw cache)

Service Worker FTW

Has its own thread (remember web workers?)

No DOM access!

Caching

Versioning

Allows offline functionality

Able to intercept fetch requests

Useful in slow connectivity scenarios / li-fi

Must be served via HTTPS

It's still all javascript!

Service Worker FTW

Checking availability

Service Worker FTW

Registering a service worker

Yep, it's that easy!

Service Worker FTW

Install

First event, triggered as soon as it executes

Opportunity to start caching before being able to control clients

Service Worker FTW

Activate

When old service worker is gone

New service worker is in control

Time to migrate databases / delete old caches

Service Worker FTW

Service Worker FTW

Cool diagram!

Careful with your scope!

Service Worker FTW

Skipping the waiting phase

When you really want old service worker gone

Service Worker FTW

Updating... Manually?  ¯\_(⊙︿⊙)_/¯

It's also possible to force an update via code!

Service Worker FTW

You can detect when you're online and offline!

Service Worker FTW

Services workers aren't the only ones who can access​​​​​ cache storage

Service Worker FTW

P is for Performance!

The web is for everyone!

The biggest emerging markets do not have widespread high bandwith data (e.g. 4G)

Not everybody has an iMac 8K or a Samsung Galaxy Edge 27 Chrome Edition

We have to make sure it's snappy!

Not your average user

Your average user

VS

P is for Performance!

Useful websites for your reference:

whatdoesmysitecost.com - Know how much your website costs in a metered data connection

webpagetest.org - Test your website from all around the world plus some useful insights

Google PSI - (Page Speed Insigths) Extremely useful tool to find low hanging fruit

Google Lighthouse - Runs audits for performance, accessibility and PWAs. Can be used as a Chrome Extension or a Node module

P is for Performance!

Making your data smaller

Compress and cache

  • Easily achievable by configuring web server: github.com/h5bp/server-configs

Gzip text-based assets

Brotli for higher compression ratio

Good build tools (e.g. Webpack):

  • Tree shaking
  • Lazy loading
  • Code Splitting
  • Whatever they invent next!

P is for Performance!

Look after your image(s)

 

Include image optimisation in build process

Progressive JPEG - Progressive rendering

WebP is a modern image format that provides superior lossless and lossy compression for images on the web

Lazy load images - Intersection observer

P is for Performance!

Look after your image(s)

// create observer
const observer = new IntersectionObserver(onChange);

function onChange(changes) {
	changes.forEach(change => {
	    // take image url from `data-src` attribute
	    change.target.src = change.target.dataset.src;

	    // stop observing the current target
	    observer.unobserve(change.target);
  	});
}

// convert node list to array
const imgs = [ ...document.querySelectorAll('.lazy') ];

// observe each image
imgs.forEach(img => observer.observe(img));

P is for Performance!

FONTS!

Optimise web fonts - use lightweight woff2

Most browsers don't render text until the font is available

Users have to wait to read text they likely already have

body {
    font-family: Arial, sans-serif;
}

body.has-fonts-loaded {
    font-family: "My fancy font";
}
someFontLoader
    .load('My fancy font')
    .then(() => {
        document.body.classList.add('has-fonts-loaded');
});

CSS

JS

P is for Performance!

FONTS!

Most browsers don't render text until the font is available

Users have to wait to read text they likely already have

@font-face {
  font-family: MySuperDuperFont;
  src: url(/path/to/fonts/MySuperDuperFont.woff) format('woff'),
       url(/path/to/fonts/MySuperDuperFont.eot) format('eot');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

P is for Performance!

Golden Rule


Inline critical CSS & load the rest async

Critical CSS within first 14kb

 

Why that number? First round trip data

The last slide, phew!

OK, I'll shut up now.

Unless, maybe...

Questions?

PWA Crash Course - 2018

By ajrkemp

PWA Crash Course - 2018

  • 1,031