Progressive Web Apps

(aka PWA)

WHAT

@trishulgoel

@trishulgoel

WEBSITE

NATIVE APP

PWA

@trishulgoel

Discoverability

of

web

Retention

of

app

PWA

@trishulgoel

"they’re just websites that took all the right vitamins."

- Alex Russell

https://medium.com/@slightlylate/progressive-apps-escaping-tabs-without-losing-our-soul-3b93a8561955

WHY

@trishulgoel

PUSH NOTIFICATIONS

APP LIKE EXPERIENCE

@trishulgoel

WORKS OFFLINE

FASTER LOAD TIME

INSTALLABLE

@trishulgoel

HOW

@trishulgoel

Web app manifest

@trishulgoel

{
  "short_name": "App",
  "name": "My App",
  "icons": [
    {
      "src": "/images/logo.png",
      "type": "image/png",
      "sizes": "1282x128"
    }
  ],
  "start_url": "/index.html",
  "background_color": "#FF00FF",
  "display": "standalone",
  "theme_color": "#FF01FF"
}

  <link rel="manifest" href="/manifest.json">

SERVICEWORKERS

@trishulgoel

BUILDING BLOCKS OF PWA

@trishulgoel

@trishulgoel

CACHING

@trishulgoel

self.addEventListener('install', function(event) {
  event.waitUntil(
    caches.open('my-cahce').then(function(cache) {
      return cache.addAll(
        [
          '/css/style.css',
          '/js/script.js',
          '/index.html'
        ]
      );
    })
  );
});

self.addEventListener('fetch', function(event) {
  event.respondWith(
    caches.match(event.request).then(function(response) {
      if(!response) response = fetch(event.request);
      return response;
    })
  );
});

@trishulgoel

PUSH NOTIFICATIONS

@trishulgoel

self.addEventListener('activate', async () => {
  try {
    const options = {}
    const subscription = await self.registration.pushManager.subscribe(options)
  } catch (err) {
    console.log('Error', err)
  }
})

self.addEventListener('push', function(event) {
  if (event.data) {
    self.registration.showNotification("Here we are", event.data.text(),
  }
})

PWA on STEROIDS

@trishulgoel

PREREQUISITES

@trishulgoel

- HTTPS

- Browser Compatibility

@trishulgoel

STEROIDS

@trishulgoel

SPEECH SYNTHESIS

@trishulgoel


 const synth = window.speechSynthesis;
 const voices = synth.getVoices();

 const say = new SpeechSynthesisUtterance(text);
 say.voice = voices[<dialect>];
 say.rate = <rate>;
 say.pitch = <pitch>;
 
 synth.speak(say);

SPEECH RECOGNITION

@trishulgoel


 const recognition = new webkitSpeechRecognition();
 recognition.onstart = fn;
 recognition.onerror = fn;
 recognition.onend = fn;
 recognition.onresult = fn;
 recognition.start();

MEDIA CAPTURE API

@trishulgoel


 const video = document.querySelector('video');
    
 navigator.mediaDevices.getUserMedia({ video: true, audio: false })
 .then(stream => { 
     video.srcObject = stream;
     video.play();
 });

BATTERY API*

@trishulgoel


 navigator.getBattery().then(function(battery) {
     // battery.charging
     // battery.level
     battery.addEventListener('chargingchange', listener);
     battery.addEventListener('levelchange', listener);
     battery.addEventListener('chargingtimechange', listener);
 }

https://developer.mozilla.org/en-US/docs/Web/API/Battery_Status_API

NETWORK INFO

@trishulgoel


 navigator.onLine
 window.addEventListener('online',  fn);
 window.addEventListener('offline',  fn);

 navigator.connection.type
 navigator.connection.effectiveType //bandwidth
 navigator.connection.saveData
 navigator.connection.downlink

 navigator.connection.addEventListener('change', fn);

ORIENTATION

@trishulgoel


 window.addEventListener('deviceorientation', handleOrientation);

 function handleOrientation(event) {
    const z = event.alpha; // Z-aixs
    const x = event.beta;  // X-aixs | In degree in the range [-180,180]
    const y = event.gamma; // Y-aixs | In degree in the range [-90,90]
 }

WEB SHARE API*

@trishulgoel


 navigator.share({
     title: <title>
     text: <text>,
     url: <url>,
 });

https://developer.mozilla.org/en-US/docs/Web/API/Navigator/share

BLUETOOTH

@trishulgoel


 const device = await navigator.bluetooth.requestDevice({
      filters: [{
        namePrefix: 'Device-name',
        services: ['battery_service'] }],
 });

 const server = await device.gatt.connect();
 const service = await server.getPrimaryService('battery_service');
 const characteristic = await service.getCharacteristic('battery_level');

 characteristic.writeValue(new Uint8Array( .... )); // 'value' -> bytes
 characteristic.addEventListener('characteristicvaluechanged', fn); 

MANY MORE...

@trishulgoel

- web Audio API

- Payment Request API

- Memory API

- WebUSB API

SUCCESS STORIES

@trishulgoel

@trishulgoel

https://developers.google.com/web/showcase/

FUTURE

@trishulgoel

- WEBASSEMBLY 😎

- MORE APIs

- BETTER BROWSER SUPPORT

@trishulgoel

REFERENCES

- https://serviceworke.rs

- https://developer.mozilla.org

- https://developers.google.com/

@trishulgoel

@trishulgoel

Dziękuję wszystkim

PWA on Steroids

By Trishul Goel

PWA on Steroids

PWA on Steroids - Infoshare Gdańsk | Poland

  • 1,053