service workers

27
Service Workers: into & usage By: Pavel Zhytko ([email protected])

Upload: pavel-zhytko

Post on 12-Apr-2017

246 views

Category:

Technology


0 download

TRANSCRIPT

Page 1: Service workers

Service Workers: into & usage

By: Pavel Zhytko ([email protected])

Page 2: Service workers

I. Why?

Page 3: Service workers

Ultimate Goal: Progressive Apps

* First who then what:

Alex Russell - Progressive Web Apps: Escaping Tabs Without Losing Our Soul(June 15, 2015)Addy Osmani - Getting started with Progressive Web Apps (Dec 23, 2015) <- A MUST!Pete LePage (developers.google.com) - Your First Progressive Web AppGoogle Developers central repoStackoverflow tag

* what:

“A Progressive Web App uses modern web capabilities to deliver an app-like user experience.

They evolve from pages in browser tabs to immersive, top-level apps, maintaining the web's lowfriction at every moment.

Page 4: Service workers

Progressive - Built with progressive enhancement as a core principle

Responsive - Fit any form factor, desktop, mobile, tablet, or whatever is next

Linkable - Easily share via URL and not require complex installation

App-like - Use the app-shell model to provide app-style navigations and interactions

Installable - Allow users to “keep” apps they find most useful on their home screen without

the hassle of an app store

Discoverable - Search engines can index it thanks to W3C manifests and SW scope

Connectivity independent - Enhanced with Service Workers to work offline

Fresh - Always up-to-date thanks to the Service Worker update process

Safe - Served via TLS to prevent tampering (a Service Worker requirement)

Re-engageable - Make re-engagement easy through features like push notifications

(Service Worker again)

Page 5: Service workers

Prior ArtProprietary:

long list...

Open Web / Custom (MDN Demo):

Detect online/offline: Network Information API, Offline.js, ...

Fetch resources with XHR

Store resources to LocalSotrage/IndexedDB

Save state locally / sync with server: Firebase etc.

Open Web / App Cache

Bad attempt: Application Cache is a Douchebag (Jake Archibald, May 08, 2012)

Page 6: Service workers

Progressive - Built with progressive enhancement as a core principle

Responsive - Fit any form factor, desktop, mobile, tablet, or whatever is next

Linkable - Easily share via URL and not require complex installation

App-like - Use the app-shell model to provide app-style navigations and interactions

Installable - Allow users to “keep” apps they find most useful on their home screen without

the hassle of an app store

Discoverable - Search engines can index it thanks to W3C manifests and SW scope

Connectivity independent - Enhanced with Service Workers to work offline

Fresh - Always up-to-date thanks to the Service Worker update process

Safe - Served via TLS to prevent tampering (a Service Worker requirement)

Re-engageable - Make re-engagement easy through features like push notifications

(Service Worker again)

Page 7: Service workers

Progressive - Built with progressive enhancement as a core principle

Responsive - Fit any form factor, desktop, mobile, tablet, or whatever is next

Linkable - Easily share via URL and not require complex installation

App-like - Use the app-shell model to provide app-style navigations and interactions

Installable - Allow users to “keep” apps they find most useful on their home screen without

the hassle of an app store

Discoverable - Search engines can index it thanks to W3C manifests and SW scope

Connectivity independent - Enhanced with Service Workers to work offline

Fresh - Always up-to-date thanks to the Service Worker update process

Safe - Served via TLS to prevent tampering (a Service Worker requirement)

Re-engageable - Make re-engagement easy through features like push notifications

(Service Worker again)

Page 8: Service workers

Web App Manifest

“What every developer should do today — Google Developers

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

{

"short_name": "Amaze App",

"name": "My Amazing Application ++",

"icons": [...],

"start_url": "/index.html",

"display": "standalone",

"orientation": "landscape"

}

Page 9: Service workers

Features:

Full-screen mode (without URL bar): (HTTPS only in Opera): "display""fullscreen"

or Standalone mode (just top bar): : "display""standalone

Orientation: "orientation": "landscape"

Add to Home Screen menu

Plus heuristic for Add to Home Screen banner (tricky; cannot control but can cancel

and know if installed)

Splash Screen ( + + ) [Chrome 47]"name""background_color""icons"

Theme color ( <meta name="theme-color" content="#db5945">)

Support:- Chrome, FF, Opera

- Edge is considering

Tools:- Web Starter Kit

- Manifest generator

- RealFaviconGenerator

Page 10: Service workers

II. How?

Page 11: Service workers

Registration

if('serviceWorker' in navigator) {

navigator.serviceWorker

.register('/service-worker.js', {scope: './' })

.then(function() { console.log('Service Worker Registered'); });

}

- Call from arbitrary page: register() method of ServiceWorkerContainer interface

- Progressive enhancement

- Fetches .js file (HTTP caching respected)

- HTTPS only! (free SSL

certs:

LetsEncrypt.org)

- Location of file on server matters (defines max scope, relaxed with Service-Worker-Allowedheader)

- If successful, code executes in ServiceWorkerGlobalScope

Page 12: Service workers

ServiceWorkerGlobalScope and Workers

- Inherits from WokerGlobalScope - has limitations / features of other JS Workers: Web Workers,

Shared Workers, ...

- Separate thread (off the main script execution thread)

- Has limited abilities, notably: no DOM access!

- Has access to new features/API: Cache, Fetch, Request/Response, ... Uses Promises heavily.

- May use importScripts() to include other script files (even from other origin)

- May run even when all app pages are closed!

- Can (and will) be terminated to free memory, resumed on events

self.addEventListener('install', function(event) {/*...*/});

self.addEventListener('activate', function(event) {/*...*/});

self.addEventListener('fetch', function(event) {/*...*/});

self.addEventListener('push', function(event) {/*...*/});

Page 13: Service workers

Installation

- install event is triggered the first time the user visits the page (subsequent visit after

registration)

- this is the first event sent to SW

- when the oninstall handler completes, the service worker is considered installed

- good place to cache assets with Promise passed to event.waitUntil()

Page 14: Service workers

Caching on install

var filesToCache = ['/home/', '/home/index.html', '/home/style.css' ];

self.addEventListener('install', function(event) {

event.waitUntil(

caches.open('v1').then(function(cache) {

return cache.addAll(filesToCache);

})

);

});

2.

- Need to add all permutations of file names ('/', '/index/html')

- If download of any resource fails - the promise is rejected and SW is not installed (OK - may be

installed next time)

- Cache may become full and cleared by browser.

Page 15: Service workers

Activation

- this step is required for SW update mechanism

- related to notion of controlled pages: even to fired until there are pages controlled by other

workers (previous version)

- new worker is considered the one that has any byte diff with old

- check state: chrome://serviceworker-internals/

- time to finish the installation, e.g. good place to remove old caches

self.addEventListener('activate', function(event) {

event.waitUntil(

caches.keys().then(function(keyList) {

return Promise.all(keyList.map(function(key) {

if (key !== 'v2') {

return caches.delete(key);

}

}));

})

);

});

Page 16: Service workers
Page 17: Service workers

Fetch

- this event with cache handling on install/activate enables Offline first

- essentially it acts as programmable network proxy- takes Request and returns Response (Fetch API), which may be any of:

- new Response(body, opts) - fetch(urlOrRequest) - caches.match(urlOrRequest)

- resembles Express middleware!

self.addEventListener('fetch', function(event) {

event.respondWith(

caches.match(event.request).then(function(response) {

return response || fetch(event.request);

})

);

});

Page 18: Service workers

Resources and tooling

2 Cooking books:- The offline cookbook [Jake Archibald]

- serviceworke.rs (Mozilla)

Tools:By Google:

sw-precache - grunt/gulp script to generate assets list to cache with globs (to use in

install/cache.addAll() )

sw-toolbox - collection of tools to help writing event handlers, including Express-style middleware

importScripts('bower_components/sw-toolbox/sw-toolbox.js');

toolbox.precache(['/index.html', '/site.css', '/images/logo.png']); /*on install*/

toolbox.router.get(':foo/index.html$', function(request, values) {

return new Response('Some text');

});

toolbox.router.get('/myapp/index.html', toolbox.networkFirst); /* Use built-in handler

designed after a strategy in Offline Cookbook */

Page 19: Service workers

Beyond OfflineFrom serviceworke.rs Cookbook:

- API Analytics - intercept each request of a client and send some information to a log API

- Load Balancer - intercept the requests to the resources and select the proper content provider

accordingly to their availability

- Request Deferrer - enqueue requests while in offline in an outbox-like buffer to perform the

operations once the connection is regained

Page 20: Service workers

Push

New API- Push API and Notification API [Chrome 42]

- Can use old Web Notifications too

- Web Push Protocol (implemented by 'web-push' NPM module)

Resources:Push Notifications on the Open Web (Google Developers) - a lot of details

serviceworke.rs

Web Push notifications from Irssi (Mozilla Hacks)

Page 21: Service workers

Registration

var endpoint;

navigator.serviceWorker.register('service-worker.js').then(function(registration) {

return registration.pushManager.getSubscription().then(function(subscription) {

if (subscription) {

return subscription;

}

return registration.pushManager.subscribe({ userVisibleOnly: true });

});

}).then(function(subscription) {

endpoint = subscription.endpoint;

// Send endpoint to server to store in nDB

}

Page 22: Service workers

Send notification (server)

var webPush = require('web-push');

webPush.setGCMAPIKey(process.env.GCM_API_KEY);

// ...

webPush.sendNotification(endpoint, ttl);

Page 23: Service workers

Receive /show notification (Service Worker)

self.addEventListener('push', function(event) {

event.waitUntil(

self.registration.showNotification('New Discounts', {

lang: 'la',

body: 'Alea iacta est',

icon: 'caesar.jpg',

vibrate: [500, 100, 500],

})

);

});

Page 24: Service workers

Background Sync (in progress)

- Specification

- sync / periodycSync

navigator.serviceWorker.ready.then(function(registration) {

registration.sync.register('outbox').then(function() {

// registration succeeded

}

});

self.addEventListener('sync', function(event) {

if (event.tag == 'outbox') {

event.waitUntil(sendEverythingInTheOutbox());

}

});

Page 25: Service workers

III. When?

Page 26: Service workers

It is coming:- isServiceWorkerReady

- waiting for Edge/Safari

Currently in production:Flipkart Lite

Medium

Twitter

...

Page 27: Service workers

Q/A