offline web com service workers - sérgio lopes

145
SERVICE WORKERS OFFLINE WEB COM

Upload: caelum

Post on 02-Dec-2014

913 views

Category:

Technology


2 download

DESCRIPTION

Palestra de Novembro de 2014 do Sérgio Lopes da Caelum sobre a nova especificação dos Service Workers e como isso muda muita coisa na Web.

TRANSCRIPT

SERVICE WORKERSOFFLINE WEB COM

@sergio_caelumsergiolopes.org

WEB. OFFLINE?

os primórdios do HTML5 offline

Application Cache API

<html manifest="demo.appcache">

Minha página offline…

CACHE MANIFEST

/index.html/imagens/logo.png/javascript/script.js/css/estilo.css

O manifesto…

CACHE MANIFEST

/index.html/imagens/logo.png/javascript/script.js/css/estilo.css

O manifesto…

NETWORK:http://www.google-analytics.com/ga.js

CACHE MANIFEST

/index.html/imagens/logo.png/javascript/script.js/css/estilo.css

O manifesto…

NETWORK:http://www.google-analytics.com/ga.js

FALLBACK:/img/avatares/ /img/avatar-generico.png

Pronto! O maravilhoso AppCache entra em ação.

Tem que acertar o mime-type no servidor.

Tem que acertar o mime-type no servidor.Não posso esquecer nenhuma URL.

Tem que acertar o mime-type no servidor.Não posso esquecer nenhuma URL.Sempre cacheia a página.

Tem que acertar o mime-type no servidor.Não posso esquecer nenhuma URL.Sempre cacheia a página.Nada pode dar erro 404 ou 500.

Tem que acertar o mime-type no servidor.Não posso esquecer nenhuma URL.Sempre cacheia a página.Nada pode dar erro 404 ou 500.Cuidado pra não cachear o manifesto.

Tem que acertar o mime-type no servidor.Não posso esquecer nenhuma URL.Sempre cacheia a página.Nada pode dar erro 404 ou 500.Cuidado pra não cachear o manifesto.Usuário não pode controlar nada.

Tem que acertar o mime-type no servidor.Não posso esquecer nenhuma URL.Sempre cacheia a página.Nada pode dar erro 404 ou 500.Cuidado pra não cachear o manifesto.Usuário não pode controlar nada.Impossível escolher o que cachear.

Tem que acertar o mime-type no servidor.Não posso esquecer nenhuma URL.Sempre cacheia a página.Nada pode dar erro 404 ou 500.Cuidado pra não cachear o manifesto.Usuário não pode controlar nada.Impossível escolher o que cachear.Potencial para detonar o 3G do usuário.

Tem que acertar o mime-type no servidor.Não posso esquecer nenhuma URL.Sempre cacheia a página.Nada pode dar erro 404 ou 500.Cuidado pra não cachear o manifesto.Usuário não pode controlar nada.Impossível escolher o que cachear.Potencial para detonar o 3G do usuário.Remover o cache é um parto.

Tem que acertar o mime-type no servidor.Não posso esquecer nenhuma URL.Sempre cacheia a página.Nada pode dar erro 404 ou 500.Cuidado pra não cachear o manifesto.Usuário não pode controlar nada.Impossível escolher o que cachear.Potencial para detonar o 3G do usuário.Remover o cache é um parto.Não posso impedir update automático.

Tem que acertar o mime-type no servidor.Não posso esquecer nenhuma URL.Sempre cacheia a página.Nada pode dar erro 404 ou 500.Cuidado pra não cachear o manifesto.Usuário não pode controlar nada.Impossível escolher o que cachear.Potencial para detonar o 3G do usuário.Remover o cache é um parto.Não posso impedir update automático.Terrível pra desenvolver e debugar.

Tem que acertar o mime-type no servidor.Não posso esquecer nenhuma URL.Sempre cacheia a página.Nada pode dar erro 404 ou 500.Cuidado pra não cachear o manifesto.Usuário não pode controlar nada.Impossível escolher o que cachear.Potencial para detonar o 3G do usuário.Remover o cache é um parto.Não posso impedir update automático.Terrível pra desenvolver e debugar. …

Tem que acertar o mime-type no servidor. Não posso esquecer nenhuma URL. Sempre cacheia a página. Nada pode dar erro 404 ou 500. Cuidado pra não cachear o manifesto. Usuário não pode controlar nada. Impossível escolher o que cachear. Potencial para detonar o 3G do usuário. Remover o cache é um parto. Não posso impedir update automático. Terrível pra desenvolver e debugar. …

AppCache é

chato, limitado e

complicado.

http://sergiolopes.org/palestra-appcache-html5-offline/

Declarativo e Mágico.

SERVICE WORKERS

<!DOCTYPE html><html><head>

</head><body><h1>Página offline</h1>

</body></html>

<!DOCTYPE html><html><head><script>navigator.serviceWorker.register('o-futuro.js');

</script></head><body><h1>Página offline</h1>

</body></html>

this.onfetch = function(event) {

console.log(event.request.url);

};

this.onfetch = function(event) {event.respondWith(

new Response("<h1>Página offline!</h1>") );};

É um Worker orientado a eventos, que controla as páginas em background. Lá, tudo é assíncrono, e

ele pode interceptar chamadas de rede e usar um cache de recursos.

SERVICE WORKER

<script src="script.js" async></script>

JAVASCRIPT COMUM

<script src="script.js" async></script>

DOM

CSSOM

LAYOUT

EVENTOS

SCROLL

JAVASCRIPT COMUM

<script src="script.js" async></script>

DOM

CSSOM

LAYOUT

EVENTOS

SCROLL

script

script

script

script

JAVASCRIPT COMUM

<script> new Worker('worker.js'); </script>

WEB WORKERS

<script> new Worker('worker.js'); </script>

DOM

CSSOM

LAYOUT

EVENTOS

SCROLL

WEB WORKERS

script script script script

<script> new Worker('worker.js'); </script>

DOM

CSSOM

LAYOUT

EVENTOS

SCROLL

WEB WORKERS

PÁGINA #1

WEB WORKERS

PÁGINA #1

web worker A

WEB WORKERS

PÁGINA #1

web worker A

WEB WORKERS

web worker B

PÁGINA #1

web worker A

WEB WORKERS

web worker B

PÁGINA #2

web worker A

web worker B

WEB WORKERS

PÁGINA #2

web worker A

web worker B

WEB WORKERS

<script>navigator.serviceWorker.register('sw.js');</script>

PÁGINA #1

Service Worker

PÁGINA #2

PÁGINA #3

SERVICE WORKER

<script>navigator.serviceWorker.register('sw.js');</script>

PÁGINA #1

Service Worker

PÁGINA #2

SERVICE WORKER

<script>navigator.serviceWorker.register('sw.js');</script>

PÁGINA #1

Service Worker

SERVICE WORKER

<script>navigator.serviceWorker.register('sw.js');</script>

Service Worker

SERVICE WORKER

É um Worker orientado a eventos, que controla as páginas em background. Lá, tudo é assíncrono, e

ele pode interceptar chamadas de rede e usar um cache de recursos.

SERVICE WORKER

navigator.serviceWorker.register('sw.js').then(function(){console.log('Registrado!');

}, function(erro) {console.log('Problemas', erro);

});

PROMISES

this.oninstall = function(event) {console.log('instalou');

};

this.onactivate = function(event) {console.log('ativou');

};

this.onfetch = function(event) {event.respondWith(

new Response("<h1>Página offline!</h1>”) );};

EVENTOS

CACHE API

caches.open('aplicacao');

caches.open('aplicacao').then(function(cache) {

});

caches.open('aplicacao').then(function(cache) { cache.add('pg.html');});

caches.open('aplicacao').then(function(cache) { cache.put('pg.html', new Response("Página offline"));});

caches.open('aplicacao').then(function(cache) { cache.add('pg.html'); cache.add('style.css');});

caches.open('aplicacao').then(function(cache) { cache.addAll([ '/index.html', '/style.css', '/logo.png', '/contato.html', 'http://code.jquery.com/jquery-2.1.1.min.js' ]); })

caches.open('aplicacao').then(function(cache) { return cache.addAll([ '/index.html', '/style.css', '/logo.png', '/contato.html', 'http://code.jquery.com/jquery-2.1.1.min.js' ]); })

this.oninstall = function(event) {

caches.open('aplicacao').then(function(cache) { return cache.addAll([ '/index.html', '/style.css', '/logo.png', '/contato.html', 'http://code.jquery.com/jquery-2.1.1.min.js' ]); })

};

this.oninstall = function(event) { event.waitUntil( caches.open('aplicacao').then(function(cache) { return cache.addAll([ '/index.html', '/style.css', '/logo.png', '/contato.html', 'http://code.jquery.com/jquery-2.1.1.min.js' ]); }) );};

CACHE programático & controlável

CACHE programático & controlável

Cacheio URLs como quero.

CACHE programático & controlável

Cacheio URLs como quero.

Gero endereços num for com certa regra.

CACHE programático & controlável

Cacheio URLs como quero.

Gero endereços num for com certa regra.

Recursos diferentes dependendo do browser.

CACHE programático & controlável

Cacheio URLs como quero.

Gero endereços num for com certa regra.

Recursos diferentes dependendo do browser.

Levo em conta alguma preferência do usuário.

CACHE programático & controlável

Cacheio URLs como quero.

Gero endereços num for com certa regra.

Recursos diferentes dependendo do browser.

Levo em conta alguma preferência do usuário.

Mudo de acordo com hardware e contexto.

RESPOSTA OFFLINE

this.onfetch = function(event) {

console.log(event.request.url);

};

this.onfetch = function(event) { event.respondWith( new Response(‘conteúdo!') );};

this.onfetch = function(event) { event.respondWith( caches.match(event.request) );};

RESPOSTA DO CACHE

RESPOSTA DO CACHEE se não existir?

this.onfetch = function(event) { event.respondWith( caches.match(event.request).then(function(response){

}) );};

this.onfetch = function(event) { event.respondWith( caches.match(event.request).then(function(response){ return response || event.default(); })

);};

BAIXA NA REDE

BAIXA NA REDEE se estiver offline?

this.onfetch = function(event) { event.respondWith( caches.match(event.request).then(function(response){ return response || event.default(); }).catch(function() { return caches.match('/contato.html'); }) );};

FALLBACK DE URLs

RESPOSTA programática & controlável

RESPOSTA programática & controlável

Busco no cache.

RESPOSTA programática & controlável

Busco no cache.

Busco na rede.

RESPOSTA programática & controlável

Busco no cache.

Busco na rede.

Devolvo fallback.

RESPOSTA programática & controlável

Busco no cache.

Busco na rede.

Devolvo fallback.

Construo resposta na mão.

RESPOSTA programática & controlável

Busco no cache.

Busco na rede.

Devolvo fallback.

Construo resposta na mão.

Tudo com a lógica e a sequência que eu quiser.

ATUALIZAÇÕES

Mudo o worker.js

Mudo o worker.jsDetecta na próxima navegação.

Mudo o worker.jsDetecta na próxima navegação.

Dispara instalação (oninstall) em background.

Mudo o worker.jsDetecta na próxima navegação.

Dispara instalação (oninstall) em background.

(worker original ainda comanda a página)

Mudo o worker.jsDetecta na próxima navegação.

Dispara instalação (oninstall) em background.

(worker original ainda comanda a página)

Fecho a página.

Mudo o worker.jsDetecta na próxima navegação.

Dispara instalação (oninstall) em background.

(worker original ainda comanda a página)

Fecho a página.

Worker velho é desativado.

Mudo o worker.jsDetecta na próxima navegação.

Dispara instalação (oninstall) em background.

(worker original ainda comanda a página)

Fecho a página.

Worker velho é desativado.

Novo worker é ativado (onactivate).

Mudo o worker.jsDetecta na próxima navegação.

Dispara instalação (oninstall) em background.

(worker original ainda comanda a página)

Fecho a página.

Worker velho é desativado.

Novo worker é ativado (onactivate).

(novo worker em ação)

Mudo o worker.jsDetecta na próxima navegação.

Dispara instalação (oninstall) em background.

(worker original ainda comanda a página)

Fecho a página.

Worker velho é desativado.

Novo worker é ativado (onactivate).

(novo worker em ação)

Abro a página de novo.

this.oninstall = function(event) { event.waitUntil( caches.open('aplicacao-v2').then(function(cache) { return cache.addAll([ '/index.html', '/style.css', '/logo.png', '/contato.html', 'http://code.jquery.com/jquery-2.1.1.min.js' ]); }) );};

this.onactivate = function(event) { event.waitUntil( caches.delete('aplicacao-v1') );};

ATUALIZAÇÃO

ATUALIZAÇÃO

Totalmente em background.

ATUALIZAÇÃO

Totalmente em background.

Não incomoda o usuário.

ATUALIZAÇÃO

Totalmente em background.

Não incomoda o usuário.

Só troca no próximo acesso.

ATUALIZAÇÃO

Totalmente em background.

Não incomoda o usuário.

Só troca no próximo acesso.

Chrome-like.

detalhes dos

SERVICE WORKERS

controle de escopo

navigator.serviceWorker.register('worker.js');

navigator.serviceWorker.register('worker.js', {scope: '/blog/'

});

HTTPS only

tudo assíncrono

pode ser morto a qualquer momento

muito mais poderoso muito mais complicado

ainda não existe em nenhum browser

FUTURO FANTÁSTICO

BACKGROUND SYNC

postaTweet(texto);

try {postaTweet(texto);

} catch (err) {

}

try {postaTweet(texto);

} catch (err) {salvaTweet(texto);registration.sync.register('envia-tweet');

}

postaTweet(texto).catch(function(){

});

postaTweet(texto).catch(function(){ salvaTweet(texto).then(function(){

}).then(function(){

});});

postaTweet(texto).catch(function(){return salvaTweet(texto).then(function(){return navigator.serviceWorker.ready;

}).then(function(registration){return registration.sync.register('envia-tweet');

});});

this.onsync = function (event) {if (event.id === 'envia-tweet') {

}};

this.onsync = function (event) {if (event.id === 'envia-tweet') {event.waitUntil(carregaTweet().then(function(texto){postaTweet(texto);

}));

}};

registration.sync.register('atualiza-inbox', {minInterval: 60 * 60 * 1000

});

PUSH NOTIFICATION

registration.pushRegistrationManager.register()

registration.pushRegistrationManager.register() .then(function(detalhes) {

});

registration.pushRegistrationManager.register() .then(function(detalhes) { return avisaServidor(detalhes);

});

this.onpush = function(event) {if (event.message.data == 'nova-mensagem') {

}};

this.onpush = function(event) {if (event.message.data == 'nova-mensagem') {event.waitUntil(atualizaMensagens().then(function(){

}));

}};

this.onpush = function(event) {if (event.message.data == 'nova-mensagem') {event.waitUntil(atualizaMensagens().then(function(){new Notification("Chegou mensagem!");

}));

}};

this.onnotificationclick = function(event) {

};

this.onnotificationclick = function(event) {new ServiceWorkerClient('/mensagens.html');

};

GEOFENCING

ALARMES TEMPORAIS

hoje, depois do evento

SERVICE WORKERS

estude Service Workers hoje. esse é o futuro.

brinque no ChromeChrome Canary - chrome://flags

#enable-experimental-web-platform-features

vote no status.modern.ie

use AppCache como fallback

offline como progressive enhancement

if ('serviceWorker' in navigator) {

}

pense offline first

SERVICE WORKERSOFFLINE WEB COM

OBRIGADO!

sergiolopes.org @sergio_caelum