Progressive Web Apps (PWA) são conjuntos de conceitos para melhorar a experiência do usuário em aplicativos web, incluindo rapidez, confiabilidade e engajamento. PWA não dependem apenas de front-end, mas também requerem cuidados com back-end, devops, imagens, arquivos estáticos e serviços como CDNs para entregar uma experiência próxima da de aplicativos nativos.
9. 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.
10. Progressive Web Apps é um
conjunto de conceitos:
Rapidez, Integridade, Confiabilidade e
Engajamento.
11. Como uma “agência”, PWA contém algumas
“auditorias” pra certificar que estamos
seguindo esses conceitos.
16. GZIP
SEVOCÊ AINDA NÃO ESTÁ
USANDO, BEM…
Nginx, Node, Apache, IIS.
Todos têm possibilidade de enviar conteúdo
comprimido com GZIP
17. 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;
23. TIME TO FIRST BYTE
O TEMPO PRA QUE O PRIMEIRO BYTE CHEGUE NO CLIENT
24. 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;
26. 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).
27. TIME TO FIRST BYTE É IMPORTANTE
PARA A PRIMEIRA EXPERIÊNCIA DO PWA.
SENSAÇÃO DEVELOCIDADE É UM DOS
ASPECTOS MAIS IMPORTANTES NUM WEB APP.
32. 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”
36. 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 CSSHint Resource Preloading
39. DNS-PREFETCH
OLHA SÓ,VAIVIR 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.
46. Preload
Faz o download de um asset, independente do
browser achar que precisa ou não.
PRELOAD
JÁ BAIXA AÍ, POR FAVOR
47. 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
48. 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" />
57. 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
58. SOBRE FONTES…
USE MENOS!
• MAIS QUE 2 FAMÍLIAS DE FONTES NUM WEB APP… PARECE ESTRANHO!
• FONTES SÃO BLOCANTES;
• CAUSAM FOIT (FLASH OF INVISIBLETEXT);
65. INPUT LATENCYSENSAÇÃO DEVELOCIDADE 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!
75. 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>
76. NÃO É ESSENCIAL DE INÍCIO? CARREGA DEPOIS!
JAVASCRIPT NÃO BLOCANTE
Com async, o JavaScript é carregado enquanto o DOM é construído.
Asim que carregado ele já é executado.
77. 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.
78. NÃO É ESSENCIAL DE INÍCIO? CARREGA DEPOIS!
JAVASCRIPT NÃO BLOCANTE
79. USE ESTRATÉGIAS DE CACHE COM
SERVICE WORKERS
Como o Service Workers funciona
80. 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);
});
};
81. 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'
]);
})
);
});
82. 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
});
})
);
});
83.
84. NETWORK FIRST? CACHE FIRST? SW-PRECACHE PRA CRIAR O ARQUIVO DO SW
USE ESTRATÉGIAS DE CACHE COM
SERVICE WORKERS
85. 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'
}]
};