Loiane Groner
Java + JavaScript/HTML5 developer • Web/Angular GDE • Microsoft MVP • author @PacktPub More decks available at: https://www.slideshare.net/loianeg
Java, JavaScript + HTML5, Sencha, Cordova/Ionic, Angular, RxJS + all things reactive
Sites Estáticos
Sites Dinâmicos
AJAX
Design Responsivo
PWAs
uma nova metodologia de desenvolvimento de software
um Progressive Web App pode ser visto como uma evolução híbrida entre as páginas da web regulares (ou sites) e um aplicativo móvel
Progressivo
Descobrível
Linkável
Responsivo
App-like
Sempre Atualizado
Instalável
Engajável
Seguro
Independente
Conexão
{
"name": "Loiane",
"short_name": "Loiane",
icons: [{
src: "images/touch/icon-96x96.png",
sizes: "96x96",
type: "image/png"
}, {
src: "images/touch/icon-128x128.png",
sizes: "128x128",
type: "image/png"
}, {
src: "images/touch/apple-touch-icon.png",
sizes: "152x152",
type: "image/png"
}, {
src: "images/touch/chrome-touch-icon-192x192.png",
sizes: "192x192",
type: "image/png"
}],
"start_url": "/index.html",
"theme_color": "#ffffff",
"background_color": "#ffffff",
"display": "standalone",
"orientation": "portrait"
}
{
"short_name": "Users",
"name": "Users PWA",
"icons": [
{
"src": "icons/android-chrome-192x192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "icons/android-chrome-512x512.png",
"sizes": "512x512",
"type": "image/png"
}
],
"scope": "/",
"start_url": "/index.html",
"orientation": "portrait",
"display": "standalone",
"theme_color": "#ffffff",
"background_color": "#ffffff"
}
<link rel="manifest" href="/manifest.json">
<link rel="stylesheet" href="assets/mdl/material.min.css" />
...
<body>
<div class="mdl-layout mdl-js-layout mdl-layout--fixed-header">
<header class="mdl-layout__header">
<div class="mdl-layout__header-row">
<span class="mdl-layout-title">Ramdom Users</span>
<div class="mdl-layout-spacer"></div>
</div>
</header>
<main class="mdl-layout__content">
<div id="first-load" class="center">
<!-- svg: ícone dos usuários -->
<p>Loading users...</p>
</div>
<div id="connection-status" class="center"></div>
<div class="mdl-grid">
<!-- Conteúdo Dinâmico-->
</div>
<div class="center">
<button onclick="pageEvents.loadMore()" class="mdl-button">
Load More
</button>
</div>
</main>
</div>
...
</body>
var cacheFiles = [
'dist/app.js',
'index.html',
'assets/mdl/material.min.css',
'assets/mdl/material.min.js'
];
// Registrar o ServiceWorker na aplicação
if ('serviceWorker' in navigator) {
navigator.serviceWorker
.register('/sw.js', {scope:''})
.then((registration) => {
// SW registrado!
});
}
// http://bit.ly/sw-lifecycle
self.addEventListener('install', (event) => {
// SW foi baixado e instalado
// Passo 1 é cachear o App Shell
// Preparar a app para funcionar offline
});
self.addEventListener('activate', (event) => {
// SW está instalado e ativo
// Podemos terminar o setup
// Ou limpar cache antigo
});
self.addEventListener('fetch', (event) => {
// Escuta cada evento
// E faz alguma coisa para cada request
// feito da app para API server
});
var CACHE_NAME = 'usersCacheV1';
var CACHE_FILES = [
'dist/app.js',
'index.html',
'assets/js/localForage/localforage.min.js',
'assets/js/localForage/localforage-getitems.js',
'assets/js/localForage/localforage-setitems.js',
'assets/mdl/material.min.css',
'assets/mdl/material.min.js'
];
self.addEventListener('install', (event) => {
// abre o cache
event.waitUntil(
caches.open(CACHE_NAME)
// e add arquivos offline no cache
.then((cache) => {
return cache.addAll(CACHE_FILES));
})
// Arquivos já cacheado!
.then(() => self.skipWaiting())
);
});
self.addEventListener('fetch', function(event){
var requestUrl = new URL(event.request.url);
var requestPath = requestUrl.pathname;
// se for imagem, request online
if(requestPath == imagePath){
event.respondWith(networkFirstStrategy(event.request));
// se for request, tenta cache primeiro e depois online
} else{
event.respondWith(cacheFirstStrategy(event.request));
}
});
Estratégias: Cache first ou Online first
function cacheFirstStrategy(request){
return caches.match(request).then(function(cacheResponse){
return cacheResponse || fetchRequestAndCache(request);
});
}
function networkFirstStrategy(request){
return fetchRequestAndCache(request).catch(function(response){
return caches.match(request);
});
}
function fetchRequestAndCache(request){
return fetch(request).then(function(networkResponse){
caches.open(getCacheName(request)).then(function(cache){
cache.put(request, networkResponse);
});
return networkResponse.clone();
});
}
let plugins = [
new WorkboxPlugin({
globDirectory: DIST_DIR,
globPatterns: ['**/*.{html,js,css,json,png}'],
swDest: path.join(DIST_DIR, 'sw.js')
})
],
...;
const workboxSW = new WorkboxSW();
const networkFirst = workboxSW.strategies.networkFirst();
workboxSW.router.registerRoute('/users', networkFirst);
fechData() {
const me = this;
me.page++;
return new Promise(function(resolve, reject) {
fetch(me.getUrlRequest())
.then(function(response) {
return response.json();
})
.then(function(data) {
me.clientStorage
.addUsers(data.results, me.page, me.resultsQtd).then(function() {
data.results.forEach(me.preCacheUserDetails);
resolve('The connection is OK, showing results from server');
});
})
.catch(function(e) {
resolve('No connection, showing offline results');
});
setTimeout(function() {
resolve('Bad connection, showing offline results');
}, 3000);
});
}
By Loiane Groner
Vamos desbravar o mundo das PWAs (Progressive Web Apps) e entender o que podemos fazer hoje na web! Há 5 anos, não podíamos tirar foto com a câmera usando o browser, e nem enviar notificações push. Hoje já podemos usar APIs com essas funcionalidades graças à evolução da web! Vamos entender o que são as PWAs e como podemos trazer a experiência de aplicações mobile para web, além de entender o que precisamos fazer para transformar aplicações web existentes em aplicações progressivas (ou como criar uma do zero). Como exemplo, usaremos o bom e velho JavaScript (ES2015+) com dicas de ferramentas para facilitar o nosso trabalho!
Java + JavaScript/HTML5 developer • Web/Angular GDE • Microsoft MVP • author @PacktPub More decks available at: https://www.slideshare.net/loianeg