$30 off During Our Annual Pro Sale. View Details »

Progressive Web Apps with React

Progressive Web Apps with React

Jonathan Mills

October 10, 2018
Tweet

More Decks by Jonathan Mills

Other Decks in Technology

Transcript

  1. @ j o n a t h a n f m i l l s
    #reactPWA
    P R O G R E S S I V E W E B A P P S W I T H R E A C T

    View Slide

  2. View Slide

  3. View Slide

  4. View Slide

  5. Progressive Web Apps
    to the rescue!

    View Slide

  6. What is a
    PWA? RELIABLE

    View Slide

  7. What is a
    PWA?
    RELIABLE
    FAST

    View Slide

  8. What is a
    PWA?
    RELIABLE
    FAST
    ENGAGING

    View Slide

  9. Demo

    View Slide

  10. View Slide

  11. Service Workers

    View Slide

  12. Have you heard of a
    Web Worker?

    View Slide

  13. ServiceWorker != WebWorker

    View Slide

  14. View Slide

  15. if('serviceWorker' in navigator) {
    navigator.serviceWorker.register('/offline.js',
    { scope: '/' })
    .then(function(registration) {
    console.log('Service Worker Registered');
    });
    navigator.serviceWorker.ready
    .then(function(registration) {
    console.log('Service Worker Ready');
    });
    }
    SERVICE WORKER

    View Slide

  16. INSTALL
    const CACHE_NAME = ‘DevUp’
    // Version 0.6.5
    self.addEventListener('install', e => {
    console.log('installing service worker!!')
    const timeStamp = Date.now();
    e.waitUntil(
    caches.open(CACHE_NAME).then(cache => {
    return cache.addAll([
    `/`,
    `/index.html`,
    `/json/data.json`,
    `/static/js/bundle.js`
    ])
    .then(() => self.skipWaiting());
    })
    );
    });

    View Slide

  17. INSTALL
    const CACHE_NAME = ‘DevUp’
    // Version 0.6.5
    self.addEventListener('install', e => {
    console.log('installing service worker!!')
    const timeStamp = Date.now();
    e.waitUntil(
    caches.open(CACHE_NAME).then(cache => {
    return cache.addAll([
    `/`,
    `/index.html`,
    `/json/data.json`,
    `/static/js/bundle.js`
    ])
    .then(() => self.skipWaiting());
    })
    );
    });

    View Slide

  18. INSTALL
    const CACHE_NAME = ‘DevUp'
    // Version 0.6.5
    self.addEventListener('install', e => {
    console.log('installing service worker!!')
    const timeStamp = Date.now();
    e.waitUntil(
    caches.open(CACHE_NAME).then(cache => {
    return cache.addAll([
    `/`,
    `/index.html`,
    `/json/data.json`,
    `/static/js/bundle.js`
    ])
    .then(() => self.skipWaiting());
    })
    );
    });

    View Slide

  19. ACTIVATE
    self.addEventListener('activate', event => {
    console.log('activating service worker');
    event.waitUntil(self.clients.claim());
    });

    View Slide

  20. FETCH
    self.addEventListener('fetch', function(event) {…})

    View Slide

  21. FETCH
    event.respondWith(
    caches.match(event.request)
    .then(function(response) {
    // Cache hit - return response
    if (response) {
    return response;
    }
    var fetchRequest = event.request.clone();
    return fetch(fetchRequest).then(
    function(response) {
    // Check if we received a valid response
    if(!response || response.status !== 200 || response.type !== 'basic'){
    return response;
    }
    var responseToCache = response.clone();
    caches.open(CACHE_NAME)

    View Slide

  22. FETCH
    event.respondWith(
    caches.match(event.request)
    .then(function(response) {
    // Cache hit - return response
    if (response) {
    return response;
    }
    var fetchRequest = event.request.clone();
    return fetch(fetchRequest).then(
    function(response) {
    // Check if we received a valid response
    if(!response || response.status !== 200 || response.type !== 'basic'){
    return response;
    }
    var responseToCache = response.clone();
    caches.open(CACHE_NAME)

    View Slide

  23. FETCH
    event.respondWith(
    caches.match(event.request)
    .then(function(response) {
    // Cache hit - return response
    if (response) {
    return response;
    }
    var fetchRequest = event.request.clone();
    return fetch(fetchRequest).then(
    function(response) {
    // Check if we received a valid response
    if(!response || response.status !== 200 || response.type !== 'basic'){
    return response;
    }
    var responseToCache = response.clone();
    caches.open(CACHE_NAME)

    View Slide

  24. event.respondWith(
    caches.match(event.request)
    .then(function(response) {
    // Cache hit - return response
    if (response) {
    return response;
    }
    var fetchRequest = event.request.clone();
    return fetch(fetchRequest).then(
    function(response) {
    // Check if we received a valid response
    if(!response || response.status !== 200 || response.type !== 'basic'){
    return response;
    }
    var responseToCache = response.clone();
    caches.open(CACHE_NAME)
    FETCH

    View Slide

  25. }
    var fetchRequest = event.request.clone();
    return fetch(fetchRequest).then(
    function(response) {
    // Check if we received a valid response
    if(!response || response.status !== 200 || response.type !== 'basic'){
    return response;
    }
    var responseToCache = response.clone();
    caches.open(CACHE_NAME)
    .then(function(cache) {
    cache.put(event.request, responseToCache);
    });
    return response;
    }
    );
    })
    );
    FETCH

    View Slide

  26. }
    var fetchRequest = event.request.clone();
    return fetch(fetchRequest).then(
    function(response) {
    // Check if we received a valid response
    if(!response || response.status !== 200 || response.type !== 'basic'){
    return response;
    }
    var responseToCache = response.clone();
    caches.open(CACHE_NAME)
    .then(function(cache) {
    cache.put(event.request, responseToCache);
    });
    return response;
    }
    );
    })
    );
    FETCH

    View Slide

  27. }
    var fetchRequest = event.request.clone();
    return fetch(fetchRequest).then(
    function(response) {
    // Check if we received a valid response
    if(!response || response.status !== 200 || response.type !== 'basic'){
    return response;
    }
    var responseToCache = response.clone();
    caches.open(CACHE_NAME)
    .then(function(cache) {
    cache.put(event.request, responseToCache);
    });
    return response;
    }
    );
    })
    );
    FETCH

    View Slide

  28. }
    var fetchRequest = event.request.clone();
    return fetch(fetchRequest).then(
    function(response) {
    // Check if we received a valid response
    if(!response || response.status !== 200 || response.type !== 'basic'){
    return response;
    }
    var responseToCache = response.clone();
    caches.open(CACHE_NAME)
    .then(function(cache) {
    cache.put(event.request, responseToCache);
    });
    return response;
    }
    );
    })
    );
    FETCH

    View Slide

  29. Demo

    View Slide

  30. View Slide

  31. Manifest

    View Slide

  32. A manifest describes
    your web page in an

    View Slide

  33. INDEX.HTML

    View Slide

  34. MANIFEST
    {
    "short_name": "Library",
    "name": “DevUp Library Demo",
    "icons": [
    {
    "src": "book.png",
    "sizes": "192X192",
    "type": "image/png"
    }
    ],
    "start_url": "./index.html",
    "display": "standalone",
    "theme_color": "#000000",
    "background_color": "#ffffff"
    }

    View Slide

  35. Demo

    View Slide

  36. View Slide

  37. Let’s Deploy

    View Slide

  38. View Slide

  39. Github Pages to
    the rescue

    View Slide

  40. PACKAGE.JSON – ADDING GH-PAGES
    {
    "name": "library",
    "version": "0.1.0",
    "private": true,
    "homepage": “https://jonathanfmills.github.io/DEVUPPWA”,
    "dependencies": {
    "gh-pages": "^1.1.0",

    },
    "scripts": {
    "predeploy": "npm run build",
    "deploy": "gh-pages -d build",
    }
    }

    View Slide

  41. Demo

    View Slide

  42. http://bit.ly/devuppwa

    View Slide

  43. @ j o n a t h a n f m i l l s
    #reactPWA
    P R O G R E S S I V E W E B A P P S W I T H R E A C T

    View Slide