Slide 1

Slide 1 text

@ChrisFerdinandi GoMakeThings.com How to run a man-in-the-middle attack on your own site for fun and profit SERVICE WORKERS

Slide 2

Slide 2 text

We’ve broken the web

Slide 3

Slide 3 text

JavaScript is a house of cards

Slide 4

Slide 4 text

No content

Slide 5

Slide 5 text

~3x increase in bandwidth over the last five years https://www.speedtest.net

Slide 6

Slide 6 text

Loading…

Slide 7

Slide 7 text

Bandwidth is not evenly distributed

Slide 8

Slide 8 text

No content

Slide 9

Slide 9 text

Chris Ferdinandi GoMakeThings.com

Slide 10

Slide 10 text

No content

Slide 11

Slide 11 text

Start End 1 What service workers are
 (and how they work) Cool things you can do 3 Strategies 2

Slide 12

Slide 12 text

What is a sevice worker? 1

Slide 13

Slide 13 text

No content

Slide 14

Slide 14 text

{SW}

Slide 15

Slide 15 text

// Initialize the service worker
 //(load this with the rest of your JS) if (navigator && navigator.serviceWorker) { navigator.serviceWorker.register('/sw.js'); }

Slide 16

Slide 16 text

Install & Activate

Slide 17

Slide 17 text

{SW}

Slide 18

Slide 18 text

// listen for requests addEventListener('fetch', function (event) { // Do something with the request... });

Slide 19

Slide 19 text

{SW}

Slide 20

Slide 20 text

A service worker is a man-in-the-middle attack on your own website (but like… a good one)

Slide 21

Slide 21 text

SSL Required

Slide 22

Slide 22 text

Service Worker Strategies 2

Slide 23

Slide 23 text

Two Approaches Network-First Offline-First

Slide 24

Slide 24 text

{SW} Network-First

Slide 25

Slide 25 text

addEventListener('fetch', (event) => { let request = event.request; request.respondWith( fetch(request).then((response) => { let copy = response.clone(); event.waitUntil(caches.open('app').then((cache) => { return cache.put(request, copy); })); return response; }).catch((error) => { return caches.match(request).then((response) => { return response; }); }) ); });

Slide 26

Slide 26 text

addEventListener('fetch', (event) => { let request = event.request; request.respondWith( fetch(request).then((response) => { let copy = response.clone(); event.waitUntil(caches.open('app').then((cache) => { return cache.put(request, copy); })); return response; }).catch((error) => { return caches.match(request).then((response) => { return response; }); }) ); });

Slide 27

Slide 27 text

addEventListener('fetch', (event) => { let request = event.request; request.respondWith( fetch(request).then((response) => { let copy = response.clone(); event.waitUntil(caches.open('app').then((cache) => { return cache.put(request, copy); })); return response; }).catch((error) => { return caches.match(request).then((response) => { return response; }); }) ); });

Slide 28

Slide 28 text

addEventListener('fetch', (event) => { let request = event.request; request.respondWith( fetch(request).then((response) => { let copy = response.clone(); event.waitUntil(caches.open('app').then((cache) => { return cache.put(request, copy); })); return response; }).catch((error) => { return caches.match(request).then((response) => { return response; }); }) ); });

Slide 29

Slide 29 text

Network-First best for frequently updated assets {[0]}

Slide 30

Slide 30 text

{SW} Offline-First

Slide 31

Slide 31 text

addEventListener('fetch', (event) => { let request = event.request; request.respondWith( caches.match(request).then((response) => { return response || fetch(request).then((response) => { let copy = response.clone(); event.waitUntil(caches.open('app').then((cache) => { return cache.put(request, copy); })); return response; }); }) ); });

Slide 32

Slide 32 text

addEventListener('fetch', (event) => { let request = event.request; request.respondWith( caches.match(request).then((response) => { return response || fetch(request).then((response) => { let copy = response.clone(); event.waitUntil(caches.open('app').then((cache) => { return cache.put(request, copy); })); return response; }); }) ); });

Slide 33

Slide 33 text

addEventListener('fetch', (event) => { let request = event.request; request.respondWith( caches.match(request).then((response) => { return response || fetch(request).then((response) => { let copy = response.clone(); event.waitUntil(caches.open('app').then((cache) => { return cache.put(request, copy); })); return response; }); }) ); });

Slide 34

Slide 34 text

addEventListener('fetch', (event) => { let request = event.request; request.respondWith( caches.match(request).then((response) => { return response || fetch(request).then((response) => { let copy = response.clone(); event.waitUntil(caches.open('app').then((cache) => { return cache.put(request, copy); })); return response; }); }) ); });

Slide 35

Slide 35 text

Offline-First best for static assets that don’t change much

Slide 36

Slide 36 text

{SW} Fallbacks (Network-First)

Slide 37

Slide 37 text

{SW} Fallbacks (Offline-First)

Slide 38

Slide 38 text

addEventListener('install', (event) => { event.waitUntil(caches.open('app').then((cache) => { cache.add(new Request('/offline/')); return cache; })); }); // Inside the fetch event… catch((error) => { return caches.match(request).then((response) => { return response || caches.match('/offline/'); }); });

Slide 39

Slide 39 text

Uses & Examples 3

Slide 40

Slide 40 text

Lil’ Rhody Seafood Looks like you're offline. Here's the important stuff… 401-555-5555 123 Lobster Drive Narragansett, RI Weekly Specials Clam Cakes - $5 Lobster Rolls - $7 Calamari - $7 Clam Chowder - $5/$8 Del’s Lemonade - $3 Show critical info when offline • Restaurants • Conferences • Hotels

Slide 41

Slide 41 text

Cache previously viewed pages • Reference Sites • News Sites • Social Networks • Utility Apps

Slide 42

Slide 42 text

Cache core assets for performance • CSS • JavaScript • Images • Fonts 🚀

Slide 43

Slide 43 text

🚀 Go Fully Offline • Apps • Games

Slide 44

Slide 44 text

Replace SPAs with MPAs

Slide 45

Slide 45 text

No content

Slide 46

Slide 46 text

No content

Slide 47

Slide 47 text

Homepage Login Dashboard Account

Slide 48

Slide 48 text

You can still render HTML with JavaScript

Slide 49

Slide 49 text

No content

Slide 50

Slide 50 text

{"} {SW} Caching API Calls (with an expiration date)

Slide 51

Slide 51 text

No content

Slide 52

Slide 52 text

No content

Slide 53

Slide 53 text

No content

Slide 54

Slide 54 text

If you only remember one thing…

Slide 55

Slide 55 text

JavaScript is a house of cards

Slide 56

Slide 56 text

No content