Real World Lessons in Progressive Web Application & Service Worker Caching

Post on 08-Apr-2017

616 Views

Category:

Technology

2 Downloads

Preview:

Click to see full reader

Transcript

REAL WORLD LESSONS IN PROGRESSIVE WEB APPLICATION/SERVICE WORKER CACHINGHow Developers Can Build Web Sites With Native App User Experience and the Natural Advantages the Web Offers Businesses and Customers

http://bit.ly/2j3sAlG

@chrislove

chris@love2dev.com

www.love2dev.com

CHRIS LOVE

http://bit.ly/2j3sAlG

@chrislove

chris@love2dev.com

www.love2dev.com

CHRIS LOVE

RESOURCES

Slide URL slideshare – https://slideshare.com/docluv

Source Code – https://github.com/docluv

PROGRESSIVE WEB APPLICATION COURSE

VideosE-bookChecklistsReference Source CodeBuild Scripts

$97LimitedTime!

Presentation Title Can Be Placed Here 6

PUBLIC LOGO

We Made a PWA Logo Creative Common License! https://github.com/docluv/pwa-logo

Presentation Title Can Be Placed Here 7

LIFE CYCLE

SERVICE WORKER

Presentation Title Can Be Placed Here 8

LIFE CYCLE Lives Separate From Page Must Register Service Worker The Service Worker is Installed It is not Immediately Active

Can be Forced Active Upon Install Activated After All Current References Terminated Now Controls All New Instances of Site

Web Server

Web Page

Service Worker

Cache

2

1

Web Server

Web Page

Service Worker

Cache

2

Presentation Title Can Be Placed Here 12

REGISTRATIONif ('serviceWorker' in navigator) {     navigator.serviceWorker.register('/sw.js')

.then(function(registration) {       // Registration was successful    })

.catch(function(err) {       // registration failed :(    }); }

Presentation Title Can Be Placed Here 13

INSTALL

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

//do something

});

Presentation Title Can Be Placed Here 14

ACTIVATE

self.addEventListener('activate', function (event) { console.log('Service Worker activating.');});

Presentation Title Can Be Placed Here 15

ACTIVATEself.addEventListener('install', function (e) {

e.waitUntil(…})); self.skipWaiting();});

THE PROXY SERVER IN YOUR POCKET

SERVICE WORKER

Presentation Title Can Be Placed Here 18

CLASSIC WEB CLIENT-SERVER

Web Server

Web Page

Presentation Title Can Be Placed Here 19

ADD SERVICE WORKER

Web ServerWeb Page

Service Worker

Presentation Title Can Be Placed Here 20

Web ServerWeb

Page

Service Worker

Presentation Title Can Be Placed Here 21

Web ServerWeb

Page

Service Worker

Cache

Presentation Title Can Be Placed Here 22

SERVICE WORKER CACHE

Persist Files with Response HeadersLimited by Device ResourcesAvailable Online & Offline

Presentation Title Can Be Placed Here 23

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

e.waitUntil( caches.open(cacheName).then(function (cache) {

return cache.addAll(filesToCache).catch(function (error) { console.log(error);

}); }) );});

Presentation Title Can Be Placed Here 24

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

//intercept fetch request (any request from the UI thread for a file or API) and return from cache or get from server & cache it event.respondWith(

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

return resp || fetchAsset(event);

})

);

});

Web ServerWeb

Page

Service Worker

CacheIndexDB

Presentation Title Can Be Placed Here 26

THE CACHE STRATEGIES

SERVICE WORKER

Web Page

Service Worker

Web Page

Service Worker

Cache

Presentation Title Can Be Placed Here 29

OFFLINE COOKBOOK

JAKE ARCHIBALDChrome Team

https://jakearchibald.com/2014/offline-cookbook/

self.addEventListener('install', function(event) { event.waitUntil( caches.open('mysite-static-

v3').then(function(cache) {

return cache.addAll([ '/css/whatever-v3.css',

'/css/imgs/sprites-v6.png', '/css/fonts/whatever-v8.woff', '/js/all-min-v4.js' // etc

]); }) ); });

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

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

cache.addAll( // levels 11-20 ); return cache.addAll(

// core assets & levels 1-10 ); })

); });

self.addEventListener('activate', function(event) { event.waitUntil( caches.keys()

.then(function(cacheNames) { return Promise.all(

cacheNames.filter(function(cacheName) { // Return true if you want to remove this cache, // but remember that caches are shared across // the whole origin })

.map(function(cacheName) { return caches.delete(cacheName);

}) );

}) );

});

document.querySelector('.cache-article').addEventListener('click', function(event) {

event.preventDefault(); var id = this.dataset.articleId; caches.open('mysite-article-' + id)

.then(function(cache) { fetch('/get-article-urls?id=' +

id).then(function(response) { response.json();

}).then(function(urls) { cache.addAll(urls); });

}); });

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

caches.open('mysite-dynamic').then(function(cache) {

return cache.match(event.request).then(function (response) {

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

cache.put(event.request, response.clone()); return response;

}); });

}) );

});

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

caches.open('mysite-dynamic').then(function(cache) {

return cache.match(event.request).then(function(response) {

var fetchPromise = fetch(event.request).then(function(networkResponse) {

cache.put(event.request, networkResponse.clone());

return networkResponse; }) return response || fetchPromise;

}) }) ); });

self.addEventListener('install', function(event) { event.waitUntil( caches.open('mysite-static-

v3').then(function(cache) {

return cache.addAll([ '/css/whatever-v3.css',

'/css/imgs/sprites-v6.png', '/css/fonts/whatever-v8.woff', '/js/all-min-v4.js' // etc

]); }) ); });

self.addEventListener('fetch', function(event) { // If a match isn't found in the cache, the

response // will look like a connection error

event.respondWith(caches.match(event.request)); });

self.addEventListener('fetch', function(event) { event.respondWith(fetch(event.request));

// or simply don't call event.respondWith, which

// will result in default browser behavior });

self.addEventListener('fetch', function(event) { event.respondWith( caches.match(event.request)

.then(function(response) { return response ||

fetch(event.request); })

); });

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

promiseAny([ caches.match(event.request),

fetch(event.request) ])

); });

self.addEventListener('fetch', function(event) { event.respondWith( fetch(event.request).catch(

function() { return caches.match(event.request); })

); });

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

caches.open('mysite-dynamic').then(function(cache) {

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

cache.put(event.request, response.clone());

return response; });

}) );

});

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

event.respondWith(caches.match(event.request)

.then(function(response) { return response ||

fetch(event.request);}).catch(function() {

return caches.match('/offline.html');

}) );

});

CACHE TOOLS

SERVICE WORKER

Presentation Title Can Be Placed Here 62

SERVICE WORKER TOOLS

sw_precache A node module to generate service worker code that

will precache specific resources so they work offline. https://github.com/googlechrome/sw-precache

sw_toolbox A collection of service worker tools for offlining

runtime requests https://github.com/GoogleChrome/sw-toolbox

top related