Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Construindo Progressive Web Apps - GDG Mogi Guaçu 2019

Construindo Progressive Web Apps - GDG Mogi Guaçu 2019

Roger Albino

January 26, 2019
Tweet

More Decks by Roger Albino

Other Decks in Programming

Transcript

  1. Construindo Progressive Web Apps

    View Slide

  2. Roger Albino
    rogeralbino.com.br

    View Slide

  3. View Slide

  4. Confiável

    View Slide

  5. Rápido

    View Slide

  6. Envolvente

    View Slide

  7. Progressive
    Web
    App

    View Slide

  8. PWA
    Web

    View Slide

  9. Apps Híbridos Não são
    PWAs

    View Slide

  10. Seguro (https)

    View Slide

  11. Compartilhável
    (via URL)
    https://pokedex.org/
    https://pokedex.org/#/pokemon/1
    https://pokedex.org/#/pokemon/2

    View Slide

  12. Encontrável

    View Slide

  13. Responsivo

    View Slide

  14. PWA
    App

    View Slide

  15. View Slide

  16. App
    • Câmera / Galeria de Fotos

    • Microfone

    • Geolocalização

    • Contatos

    • Bluetooth

    • Outros…
    • Push Notifications

    • Icone de acesso

    • Splash Screen

    • Processos rodando em
    Background (service
    workers)

    • Offline

    View Slide

  17. É só Mobile?

    View Slide

  18. View Slide

  19. Meu PWA é instalável?

    View Slide

  20. Add to Home-screen no
    Android
    https://developers.google.com/web/fundamentals/app-install-banners/?hl=pt-br

    View Slide

  21. Add to Home-screen no
    iOS

    View Slide

  22. Add to Home-screen no
    Desktop

    View Slide

  23. Mas e as lojas de aplicativos?

    View Slide

  24. View Slide

  25. View Slide

  26. https://docs.microsoft.com/en-us/microsoft-edge/progressive-web-apps/microsoft-store

    View Slide

  27. Mas já tem tudo isso
    funcionando?

    View Slide

  28. PWA
    Progressive

    View Slide

  29. PWA
    QR Code
    Cod: 10346

    View Slide

  30. PWA
    Javascript

    View Slide

  31. Independente da
    conexão

    View Slide

  32. Progressive
    Web
    App

    View Slide

  33. Progressive
    Web
    App

    View Slide

  34. Progressive
    Web
    App

    View Slide

  35. PWA vs Nativo

    View Slide

  36. Instalável
    Nativo

    View Slide

  37. Mais familiar
    para o usuário
    Nativo

    View Slide

  38. Melhor uso
    do hardware
    Nativo

    View Slide

  39. Mais rápido
    (UI carregada quase
    instantaneamente)
    Nativo

    View Slide

  40. Envolvente
    (push notifications)
    Nativo

    View Slide

  41. Recursos que somente
    APPs Nativas tem
    Nativo

    View Slide

  42. Nativo
    Recursos que somente
    APPs Nativas tem
    Por enquanto…

    View Slide

  43. PWA
    O Poder da Web

    View Slide

  44. O Mesmo código para
    (web, iOS, android, desktop…)
    PWA

    View Slide

  45. Tecnologias que a gente
    já conhece
    (HTML, CSS e JS)
    PWA

    View Slide

  46. Com poderes que antes só
    conseguíamos ter com APPs
    nativas.
    PWA

    View Slide

  47. Testar o seu PWA
    Lighthouse

    View Slide

  48. View Slide

  49. View Slide

  50. Alguns exemplos
    interessantes
    pwa.rocks

    View Slide

  51. View Slide

  52. View Slide

  53. // index.html



    ...



    ...



    View Slide

  54. // index.html



    ...



    ...


    ...



    View Slide

  55. // index.html



    ...



    ...


    ...


    ...



    View Slide

  56. // index.html



    ...



    ...


    ...


    ...








    View Slide

  57. // index.html



    ...



    ...


    ...


    ...









    View Slide


  58. ...

    ...

    // index.html

    View Slide

  59. {
    "name": “My PWA”,
    "short_name": "Weather",
    "icons": [{
    "src": "images/icons/icon-128x128.png",
    "sizes": "128x128",
    "type": "image/png"
    }, {
    "src": "images/icons/icon-144x144.png",
    "sizes": "144x144",
    "type": "image/png"
    }, {
    "src": "images/icons/icon-152x152.png",
    "sizes": "152x152",
    "type": "image/png"
    }, {
    "src": "images/icons/icon-192x192.png",
    "sizes": "192x192",
    "type": "image/png"
    }, {
    "src": "images/icons/icon-256x256.png",
    "sizes": "256x256",
    "type": "image/png"
    }],
    "start_url": "/index.html",
    "display": "standalone",
    "background_color": "#3E4EB8",
    "theme_color": "#2F3BA2"
    }
    // manifest.json

    View Slide

  60. {
    "name": “My PWA”,
    "short_name": "Weather",
    "icons": [{
    "src": "images/icons/icon-128x128.png",
    "sizes": "128x128",
    "type": "image/png"
    }, {
    "src": "images/icons/icon-144x144.png",
    "sizes": "144x144",
    "type": "image/png"
    }, {
    "src": "images/icons/icon-152x152.png",
    "sizes": "152x152",
    "type": "image/png"
    }, {
    "src": "images/icons/icon-192x192.png",
    "sizes": "192x192",
    "type": "image/png"
    }, {
    "src": "images/icons/icon-256x256.png",
    "sizes": "256x256",
    "type": "image/png"
    }],
    "start_url": "/index.html",
    "display": "standalone",
    "background_color": "#3E4EB8",
    "theme_color": "#2F3BA2"
    }
    // manifest.json

    View Slide

  61. // index.html

    ...

    content="black">




    ...

    View Slide

  62. // index.html

    ...

    ...

    View Slide

  63. Service Workers
    • Não acessa o DOM

    • Roda em background (mesmo com o
    APP fechado)

    • Apenas um para várias abas do
    navegador

    • Exigem HTTPS (ou localhost)

    • Só intercepta requests do mesmo
    domínio

    View Slide

  64. // app.js
    if ('serviceWorker' in navigator) {
    navigator.serviceWorker
    .register('./service-worker.js')
    .then(function() { console.log('Service
    Worker Registered'); });
    }

    View Slide

  65. // service-worker.js
    var dataCacheName = 'weatherData-v1';
    var cacheName = 'weatherPWA-step-8-1';
    var filesToCache = [
    '/',
    '/index.html',
    '/scripts/app.js',
    '/styles/inline.css',
    '/images/clear.png',
    '/images/cloudy-scattered-showers.png',
    '/images/cloudy.png',
    '/images/fog.png',
    '/images/ic_add_white_24px.svg',
    '/images/ic_refresh_white_24px.svg',
    '/images/partly-cloudy.png',
    '/images/rain.png',
    '/images/scattered-showers.png',
    '/images/sleet.png',
    '/images/snow.png',
    '/images/thunderstorm.png',
    '/images/wind.png'
    ];

    View Slide

  66. // service-worker.js
    self.addEventListener('install', function(e) {
    console.log('[ServiceWorker] Install');
    e.waitUntil(
    caches.open(cacheName).then(function(cache) {
    console.log('[ServiceWorker] Caching app
    shell');
    return cache.addAll(filesToCache);
    })
    );
    });

    View Slide

  67. // service-worker.js
    self.addEventListener('activate', function(e) {
    console.log('[ServiceWorker] Activate');
    e.waitUntil(
    caches.keys().then(function(keyList) {
    return Promise.all(keyList.map(function(key) {
    if (key !== cacheName && key !== dataCacheName) {
    console.log('[ServiceWorker] Removing old cache', key);
    return caches.delete(key);
    }
    }));
    })
    );
    return self.clients.claim();
    });

    View Slide

  68. // service-worker.js
    self.addEventListener('fetch', function(e) {
    console.log('[Service Worker] Fetch', e.request.url);
    e.respondWith(
    caches.match(e.request).then(function(response) {
    return response || fetch(e.request);
    })
    );
    });

    View Slide

  69. Frameworks

    View Slide

  70. Angular
    ng add @angular/pwa --project *project-name*

    View Slide

  71. Vue.js

    View Slide

  72. ReactJS with CRA (create-react-app)
    // serviceWorker.unregister();
    serviceWorker.register();

    View Slide

  73. View Slide

  74. importScripts('https://storage.googleapis.com/workbox-cdn/releases/3.6.1/
    workbox-sw.js');

    View Slide

  75. workbox.routing.registerRoute(
    // Cache CSS files
    /.*\.css/,
    // Use cache but update in the background ASAP
    workbox.strategies.staleWhileRevalidate({
    // Use a custom cache name
    cacheName: 'css-cache',
    })
    );

    View Slide

  76. workbox.routing.registerRoute(
    // Cache image files
    /.*\.(?:png|jpg|jpeg|svg|gif)/,
    // Use the cache if it's available
    workbox.strategies.cacheFirst({
    // Use a custom cache name
    cacheName: 'image-cache',
    plugins: [
    new workbox.expiration.Plugin({
    // Cache only 20 images
    maxEntries: 20,
    // Cache for a maximum of a week
    maxAgeSeconds: 7 * 24 * 60 * 60,
    })
    ],
    })
    );

    View Slide

  77. workbox.googleAnalytics.initialize();

    View Slide

  78. View Slide