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

Segredos não ditos de PWA - muito além do Web A...

Segredos não ditos de PWA - muito além do Web App Manifest

Nessa palestra vamos descobrir quais coisas além dos conceitos básicos de Progressive Web Apps são ignoradas na hora de produzir uma aplicação web, de alta performance.

Eduardo Matos

October 21, 2017
Tweet

More Decks by Eduardo Matos

Other Decks in Technology

Transcript

  1. SEGREDOS NÃO DITOS DE PWA M U I TO A

    L É M D O W E B A P P M A N I F E S T
  2. D E V N A E S T R A

    DA . C O M . B R
  3. H T T P : / / D I V

    E R S I DA D E . T E C H
  4. H T T P S : / / G I

    T H U B . C O M / F R O N T E N D B R
  5. Public Work Administrations era uma agência do governo dos EUA

    pra cuidar de grandes construções públicas na década de 30/40. Só de curiosidade mesmo.
  6. Progressive Web Apps é um 
 conjunto de conceitos:
 Rapidez,

    Integridade, Confiabilidade e Engajamento.
  7. GZIP SE VOCÊ AINDA NÃO ESTÁ USANDO, BEM… Nginx, Node,

    Apache, IIS.
 Todos têm possibilidade de enviar conteúdo 
 comprimido com GZIP
  8. GZIP NGINX # Enable gzip compression.
 gzip on; # Compression

    level (1-9) # 5 is a perfect compromise between size and CPU usage
 gzip_comp_level 5; # Don't compress anything that's already small and unlikely to shrink much
 gzip_min_length 256;
  9. npm install compression --save const compression = require('compression'); const express

    = require('express'); const app = express(); app.use(compression()); GZIP NODE
  10. AUTOMATIZE imagemin-webpack-plugin gulp-imagemin middleman-imageoptim imagemin USE FERRAMENTAS NO BUILD DO

    PROJETO PRA COMPRESSÃO TODAS USAM QUASE AS MESMAS LIBS DE OTIMIZAÇÃO
  11. TIME TO FIRST BYTE • Tempo pra envio da requisição

    HTTP; • Tempo para o servidor processar a requisição; • Tempo para o servidor responder o primeiro byte;
  12. TIME TO FIRST BYTE TEMPO DE SERVIDOR, REQUEST TIME… •

    Aqui não tem jeito: precisa melhorar o tempo de resposta do servidor; • Dá pra usar cache na frente pra amenizar (Varnish, ou outra tecnologia); • Ou uma CDN (veremos logo mais).
  13. TIME TO FIRST BYTE É IMPORTANTE PARA A PRIMEIRA EXPERIÊNCIA

    DO PWA. SENSAÇÃO DE VELOCIDADE É UM DOS ASPECTOS MAIS IMPORTANTES NUM WEB APP.
  14. SINCRONIA DE DADOS POUCHDB É UMA IMPLEMENTAÇÃO COM JAVASCRIPT DO

    COUCHDB. O OBJETIVO É EMULAR O COUCHDB RODANDO NO BROWSER OU ATÉ MESMO NO NODEJS
  15. const PouchDB = require('pouchdb'); // sample === database name const

    db = new PouchDB('http://localhost:5984/sample'); const myUser = { _id: 'Edu-v1', name: 'Eduardo Matos', email: '[email protected]', company_name: 'GetNinjas', };
  16. db.find({ selector: { _id: myUser._id } }) .then((result) => {

    db.put(myUser) .then(doc => console.log('created:', doc)) .catch((err) => { const updatedUser = Object.assign({ _rev: result.docs[0]._rev }, myUser); if (err.name === 'conflict') { db.put(updatedUser).then((user) => { console.log('putted =>', user); }); } }); });
  17. SINCRONIA DE DADOS const PouchDB = require('pouchdb'); // sample ===

    database name const db = new PouchDB('sample'); db.sync('http://localhost:5984/sample', { live: true, retry: true }); VERSÃO “NO-BRAINER”
  18. PAGESPEED MAIS DE 40 FILTROS DE OTIMIZAÇÃO Combine CSS Combine

    JS Filters and Options for Optimizing Images Prioritize Critical CSS Lazily Load Images Remove Quotes Move CSS to Head Inline Preview Images Inline Google Fonts API CSS Hint Resource Preloading
  19. PAGESPEED MAIS DE 40 FILTROS DE OTIMIZAÇÃO pagespeed on; pagespeed

    FileCachePath /var/ngx_pagespeed_cache; pagespeed LogDir /var/log/pagespeed; # config pagespeed LowercaseHtmlNames on; pagespeed EnableFilters remove_comments; pagespeed EnableFilters collapse_whitespace; pagespeed EnableFilters remove_quotes; pagespeed EnableFilters elide_attributes;
  20. DNS-PREFETCH OLHA SÓ, VAI VIR ALGO DESSE DOMÍNIO DNS-Prefetch Notifica

    o cliente que há assets que vão ser baixados dentro de um domínio, assim que o browser resolver o DNS do mesmo.
  21. DNS-PREFETCH OLHA SÓ, VAI VIR ALGO DESSE DOMÍNIO dns lookup

    | connect | ssl <link rel="dns-prefetch" href="//abs-0.twimg.com">
  22. DNS-PREFETCH OLHA SÓ, VAI VIR ALGO DESSE DOMÍNIO connect |

    ssl <link rel="dns-prefetch" href="//abs-0.twimg.com">
  23. PRECONNECT EI! JÁ CONECTA AÍ! Preconnect Parecido com o dns-prefetch,

    o preconnect faz o hand-shake e negociação de TLS de forma opcional.
  24. PRECONNECT EI! JÁ CONECTA AÍ! sem dns lookup, connect e

    ssl! <link rel="preconnect" href="//abs-0.twimg.com">
  25. Preload Faz o download de um asset, independente do browser

    achar que precisa ou não. PRELOAD JÁ BAIXA AÍ, POR FAVOR
  26. PRELOAD JÁ BAIXA AÍ, POR FAVOR <link rel="preload" href="style.css" as="style">

    <link rel="preload" href="main.js" as="script"> O “as” suporta:
 audio, document, embed, fetch, font, image, object, script, style, track, worker, video
  27. PRELOAD JÁ BAIXA AÍ, POR FAVOR em 0.6 segundos, já

    iniciou o download, e em 149ms respondeu <link rel="preload" as="script" 
 crossorigin="anonymous" 
 href="https://abs-0.twimg.com/runtime.bfc3890d94f2bd96.js" />
  28. resolução tamanho natural display size (CSS px) Pixels desnecessários bytes

    
 desnecessários 1x 110 x 110 100 x 100 110 x 110 - 100 x 100 = 2100 2100 x 4 / 1024 = 
 8 KB 1x 410 x 410 400 x 400 410 x 410 - 400 x 400 = 8100 8100 x 4 / 1024 = 
 31.6 KB 1x 810 x 810 800 x 800 810 x 810 - 800 x 800 = 16100 16100 x 4 / 1024 =
 62.9 KB 2x 220 x 220 100 x 100 210 x 210 - (2 x 100) x (2 x 100) = 8400 8400 x 4 / 1024 =
 32.8 KB 2x 820 x 820 400 x 400 820 x 820 - (2 x 400) x (2 x 400) = 32400 32400 x 4 / 1024 =
 126.5 KB 2x 1620 x 1620 800 x 800 1620 x 1620 - (2 x 800) x (2 x 800) = 64400 64400 x 4 / 1024 =
 251.6 KB
  29. SOBRE FONTES… 
 USE MENOS! • MAIS QUE 2 FAMÍLIAS

    DE FONTES NUM WEB APP… PARECE ESTRANHO! • FONTES SÃO BLOCANTES; • CAUSAM FOIT (FLASH OF INVISIBLE TEXT);
  30. var fonts = [ { name: 'Lato', weight: 400 },

    { name: 'Lato', weight: 700 }, { name: 'Lato', weight: 900 } ]; fonts.forEach(function(font, index) { fonts[index].observer = new FontFaceObserver(font.name, { 
 weight: font.weight 
 }); }); Promise .all(fonts.map(function(font) { return font.observer.load(); })) .then(() => document.body.classList.remove("default-font") );
  31. INPUT LATENCY SENSAÇÃO DE VELOCIDADE NO INPUT DO USUÁRIO •

    O ideal é a interação de input ser menor que 100ms. • Digitar, Clicar, Mover sobre hover, etc. Mais que 100ms, repense muito!
  32. NÃO É ESSENCIAL DE INÍCIO? CARREGA DEPOIS! JAVASCRIPT NÃO BLOCANTE

    <!doctype html> <html> <head> <title>Testing</title> </head> <body> <script src="main.js" async></script> <script src="page.js" async></script> </body> </html>
  33. NÃO É ESSENCIAL DE INÍCIO? CARREGA DEPOIS! JAVASCRIPT NÃO BLOCANTE

    Com async, o JavaScript é carregado enquanto o DOM é construído. Assim que carregado ele já é executado.
  34. NÃO É ESSENCIAL DE INÍCIO? CARREGA DEPOIS! JAVASCRIPT NÃO BLOCANTE

    Com defer, o JavaScript é carregado enquanto o DOM é construído também, mas só é carregado quando o DOM está 100% pronto.
  35. O QUE É SERVICE WORKERS? // index.html if ('serviceWorker' in

    navigator) { navigator.serviceWorker.register('/js/sw.js') .then(reg => { if(reg.active) { console.log('Service worker active'); } }).catch(error => { console.error('Registration failed with', error); }); };
  36. O QUE É SERVICE WORKERS? // js/sw.js self.addEventListener('install', event =>

    { event.waitUntil( caches.open('v1').then(cache => { return cache.addAll([ '/index.html', '/js/app.js', '/css/styles.css', '/images/avatar/profile/01.jpg' ]); }) ); });
  37. O QUE É SERVICE WORKERS? // js/sw.js
 self.addEventListener('fetch', (event) =>

    { event.respondWith( caches.open('v1').then((cache) => { return cache.match(event.request).then((response) => { if (response) { return response.clone(); } throw Error('Response cached missing'); }).catch((error) => { return fetch(event.request.url); //fallback para online }); }) ); });
  38. NETWORK FIRST? CACHE FIRST? SW-PRECACHE PRA CRIAR O ARQUIVO DO

    SW USE ESTRATÉGIAS DE CACHE COM SERVICE WORKERS
  39. NETWORK FIRST? CACHE FIRST? SW-PRECACHE PRA CRIAR O ARQUIVO DO

    SW USE ESTRATÉGIAS DE CACHE COM SERVICE WORKERS npm i sw-precache -g sw-precache —config=precache-config.js --verbose module.exports = { staticFileGlobs: [ 'app/css/**.css', 'app/**.html', 'app/images/**.*', 'app/js/**.js' ], stripPrefix: 'app/', runtimeCaching: [{ handler: 'cacheFirst' }] };
  40. HÁ MUITO POR TRÁS DE APENAS UM WEB APP MANIFESTO

    COM ÍCONE DE APP E INSTALAÇÃO NO DEVICE