42
Front-End Developer @ DataXu/RailsReactor

"Service Worker: Let Your Web App Feel Like a Native "

  • Upload
    fdconf

  • View
    7.847

  • Download
    0

Embed Size (px)

Citation preview

Front-End Developer @ DataXu/RailsReactor

Who is mr. ServiceWorker?

Service Worker - is a new JavaScript API, special type of Web Worker

Web Worker - script running in background in separate thread

To fill the gap between web and native apps in context

of offline-first approach and background operations.

What is the purpose of ServiceWorker?

It is about not treating offline like an error

What Is Offline First?

Offline as error :( :( :(☹ ☹ ☹ Offline first☺☺☺

Facebook - News Feed

Facebook - Commenting

Offline as error :( :( :( Offline first☺☺☺

● making apps available offline - install/update

● full control over app caches

● full control over network requests

● subscribing to push notifications

● background synchronization

What Service Worker Offers?

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

if (!registration) {

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

console.log('SW registration successful');

}).catch(function (err) {

console.log('SW Registration failed: ', err);

});

}

});

Registering Service Worker

1

2

3

4

5

6

7

8

9

Service Worker RegistrationBrowser

Network

Service Worker

importScripts( 'foo.js','bar.js');

Applicationnavigator.serviceWorker .register('/service-worker.js')

GET /service-worker.js

200 OK /service-worker.js

GET /foo.js GET /bar.js

200 OK /foo.js 200 OK /bar.js

Service Worker Registration

● navigator.serviceWorker - a place for SW API

● SW is a separate single file

● SW supports importScripts()

● SW can’t be registered from other domain

● https is required, but localhost is white-listed

● SW doesn’t have access to main app context

● SW is cached and available offline

Service Worker Gotchas

Alright, let’s install the App!

Service Worker Install Event

Browser

Network

Service Worker

Fire ”install” event

GET /service-worker.js

200 OK /service-worker.js

Is SW changed?

Yes

http://somesite.org/Is SW registered?

Yes

ApplicationRegister SW

No

var staticVersion = 1;

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

var urlsToCache = ['/', '/app.css', '/app.js', '/vendor.js'];

event.waitUntil(

caches.open('static-cache-v' + staticVersion).then(function(cache){ return cache.addAll(urlsToCache);

});

);

});

Installing The App

1

2

3

4

5

6

7

8

9

Service Worker - Installing App

Browser

Network

Service Worker

GET urlsToCache

200 OK urlsToCache

Caches

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

});

return cache.addAll( urlsToCache);

● Install - SW event that is fired when SW considered updated

● Install is fired on page load if SW content is changed

● ExtendableEvent - API allowing to pause event processing

● window.caches - place for Cache API

● All requests made from Caches and SW are processed by “classic” browser caching mechanisms (304, ETag, cache-control, and so on)

Installing The App Gotchas

Great, let’s now serve the App!

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

event.respondWith(

caches.open('static-cache-v' + staticVersion).then(function(cache) { return cache.match(event.request)

}).then(function(cachedResponse) {

return cachedResponse || fetch(event.request);

});

);

});

Serving Installed App

1

2

3

4

5

6

7

8

9

Service Worker - Serving Installed AppBrowser

Network

Service Worker

Fetchevent.request

Caches

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

})

return cache.match( event.request);

.then(function(cachedResponse) { });

Application

Response

Use cached response

Make network request

Use network response

Fire ”fetch” event

return cachedResp|| fetch(event.request);

● FetchEvent - new type of event that allows to intercept network

requests

● Everything is a Promise when it comes to Service Worker

Serving Installed App Gotchas

And it is not only about Offline-First

It’s about speeding your app at allNetwork, 2ms ping, 100Mb/s

ServiceWorker, ping and loading speed depends only on system performance

OK, and if we want to clean old stuff?

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

event.waitUntil(caches.keys().then(function(cacheNames) {

return Promise.all(cacheNames.map(function(cacheName) {

if (cacheName.startsWith('static-cache-v')

&& !cacheName.endsWith(staticVersion)) {

return caches.delete(cacheName);

}

}));

}));

});

Cleaning Old App Stuff

1

2

3

4

5

6

7

8

9

10

● Activate event is fired when new SW is taking control over the

page and can be used to clean up the old version stuff

● Service Worker has two update modes - cold (default) and hot

● In cold mode SW is activated when all the pages with current active

worker are closed and new page is opened

● In hot mode activate is fired just after install is finished

Updating The App Gotchas

Cool, let’s now notify the user about update!

function sendToClients(message) {

return self.clients.matchAll({includeUncontrolled: true})

.then(function(clients) {

clients.forEach(function(client) {

client.postMessage(message);

});

});

}

Sending Messages To Client - Service Worker Side

1

2

3

4

5

6

7

8

navigator.serviceWorker.addEventListener('message', function(event) {

// event.data is the message we received

console.log(event.data);

});

Sending Messages To Client - Application Side

event.respondWith(

fetch(event.request).then(function(response) {

return response.text().then(function(responseText) {

return new Response(

responseText.replace(/foo/g, 'bar'),

{headers: response.headers}

);

});

})

);

Modifying The Response

1

2

3

4

5

6

7

8

9

10

Fetch - new API for network requests. It is based on Promise. Say “bye-bye” to callback based XHRs.

ExtendableEvent - API allowing to pause event processing

Response - API for working with network responses

Request - API for working with network responses

Cache - API for working with network caches

New APIs That Come With SW

● We can intercept all network requests

● We can respond to requests whatever way we want

● We can fully and flexibly control network cache

● It’s network interceptor running right in browser!

Gotchas

And it is not even everything!

Push Messages

Push MessagesPush messages is a really HUGE topic.

There is a great article on Google Dev Site and nice simple demo:

http://bit.ly/web-push-article http://bit.ly/simple-push-demo

Background Sync● Gives the ability to postpone tasks until user has connectivity

● Now in state of draft, available only in Chrome 49+, and a

subject to change.

Background Sync Docs

http://bit.ly/bg-sync-docs

Service Worker Browser SupportChrome - very good (most features)

Firefox - very good (most features)

Opera - good (key features)

IE - in active development

Safari - optimistic (no support, under consideration)

Service Worker Browser Support

http://bit.ly/sw-support

Resources● Introduction To Service Worker on HTML5 Rocks :

http://www.html5rocks.com/en/tutorials/service-worker/introduction/

● Developer Guide on Chromium site:

https://www.chromium.org/blink/serviceworker

● Service Worker Cookbook by Mozilla:

https://serviceworke.rs/

● Is Service Worker Ready? by Jake Archibald (a loooot of stuff there):

https://jakearchibald.github.io/isserviceworkerready/

Resources● Service Worker Libraries maintained by Google:

https://developers.google.com/web/tools/service-worker-libraries/

● Instant Loading Web Apps with An Application Shell Architecture

https://developers.google.com/web/updates/2015/11/app-shell

● Sample project (played a little bit)

http://bit.ly/sw-application

Now go, grab latest Chrome or Firefoxand try it!

But remember - with big power comes big responsibility!

Thanks for attention!Questions?

https://facebook.com/viktor.zuhttps://www.linkedin.com/in/zozulyakviktorhttp://last.fm/user/zuzya