Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Offline Web com Service Workers - Sérgio Lopes

4,809 views

Published on

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.

Published in: Technology

Offline Web com Service Workers - Sérgio Lopes

  1. 1. OFFLINE WEB COM SERVICE WORKERS
  2. 2. sergiolopes.org @sergio_caelum
  3. 3. WEB. OFFLINE?
  4. 4. os primórdios do HTML5 offline Application Cache API
  5. 5. Minha página offline… <html manifest="demo.appcache">
  6. 6. O manifesto… CACHE MANIFEST /index.html /imagens/logo.png /javascript/script.js /css/estilo.css
  7. 7. O manifesto… CACHE MANIFEST /index.html /imagens/logo.png /javascript/script.js /css/estilo.css NETWORK: http://www.google-analytics.com/ga.js
  8. 8. O manifesto… CACHE MANIFEST /index.html /imagens/logo.png /javascript/script.js /css/estilo.css NETWORK: http://www.google-analytics.com/ga.js FALLBACK: /img/avatares/ /img/avatar-generico.png
  9. 9. Pronto! O maravilhoso AppCache entra em ação.
  10. 10. Tem que acertar o mime-type no servidor.
  11. 11. Tem que acertar o mime-type no servidor. Não posso esquecer nenhuma URL.
  12. 12. Tem que acertar o mime-type no servidor. Não posso esquecer nenhuma URL. Sempre cacheia a página.
  13. 13. 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.
  14. 14. 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.
  15. 15. 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.
  16. 16. 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.
  17. 17. 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.
  18. 18. 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.
  19. 19. 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.
  20. 20. 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.
  21. 21. 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. …
  22. 22. Tem que acertar o mime-type no servidor. Não posso esquecer nenhuma URL. Sempre cacheia AppCache a página. é Nada pode dar erro limitado 404 ou 500. e Cuidado pra não cachear o manifesto. Usuário não pode controlar nada. Impossível chato, escolher complicado. 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. …
  23. 23. http://sergiolopes.org/palestra-appcache-html5-offline/
  24. 24. Declarativo e Mágico.
  25. 25. SERVICE WORKERS
  26. 26. <!DOCTYPE html> <html> <head> </head> <body> <h1>Página offline</h1> </body> </html>
  27. 27. <!DOCTYPE html> <html> <head> <script> navigator.serviceWorker.register('o-futuro.js'); </script> </head> <body> <h1>Página offline</h1> </body> </html>
  28. 28. this.onfetch = function(event) { console.log(event.request.url); };
  29. 29. this.onfetch = function(event) { event.respondWith( new Response("<h1>Página offline!</h1>") ); };
  30. 30. 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.
  31. 31. JAVASCRIPT COMUM <script src="script.js" async></script>
  32. 32. JAVASCRIPT COMUM <script src="script.js" async></script> DOM CSSOM LAYOUT EVENTOS SCROLL
  33. 33. JAVASCRIPT COMUM <script src="script.js" async></script> DOM script CSSOM script LAYOUT script EVENTOS script SCROLL
  34. 34. WEB WORKERS <script> new Worker('worker.js'); </script>
  35. 35. WEB WORKERS <script> new Worker('worker.js'); </script> DOM CSSOM LAYOUT EVENTOS SCROLL
  36. 36. WEB WORKERS <script> new Worker('worker.js'); </script> script script script script DOM CSSOM LAYOUT EVENTOS SCROLL
  37. 37. WEB WORKERS PÁGINA #1
  38. 38. PÁGINA #1 web worker A WEB WORKERS
  39. 39. PÁGINA #1 web worker A WEB WORKERS web worker B
  40. 40. PÁGINA #1 web worker A WEB WORKERS web worker B PÁGINA #2 web worker A web worker B
  41. 41. WEB WORKERS PÁGINA #2 web worker A web worker B
  42. 42. WEB WORKERS
  43. 43. <script>navigator.serviceWorker.register('sw.js');</PÁGINA #1 Service Worker PÁGINA #2 PÁGINA #3 SERVICE WORKER
  44. 44. SERVICE WORKER <script>navigator.serviceWorker.register('sw.js');</PÁGINA #1 Service Worker PÁGINA #2
  45. 45. SERVICE WORKER <script>navigator.serviceWorker.register('sw.js');</PÁGINA #1 Service Worker
  46. 46. SERVICE WORKER <script>navigator.serviceWorker.register('sw.js');</Service Worker
  47. 47. 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.
  48. 48. PROMISES navigator.serviceWorker.register('sw.js').then(function(){ console.log('Registrado!'); }, function(erro) { console.log('Problemas', erro); });
  49. 49. EVENTOS 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>”) ); };
  50. 50. CACHE API
  51. 51. caches.open('aplicacao');
  52. 52. caches.open('aplicacao').then(function(cache) { });
  53. 53. caches.open('aplicacao').then(function(cache) { cache.add('pg.html'); });
  54. 54. caches.open('aplicacao').then(function(cache) { cache.put('pg.html', new Response("Página offline")); });
  55. 55. caches.open('aplicacao').then(function(cache) { cache.add('pg.html'); cache.add('style.css'); });
  56. 56. 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' ]); })
  57. 57. 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' ]); })
  58. 58. 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' ]); }) };
  59. 59. 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' ]); }) ); };
  60. 60. CACHE programático & controlável
  61. 61. CACHE programático & controlável Cacheio URLs como quero.
  62. 62. CACHE programático & controlável Cacheio URLs como quero. Gero endereços num for com certa regra.
  63. 63. CACHE programático & controlável Cacheio URLs como quero. Gero endereços num for com certa regra. Recursos diferentes dependendo do browser.
  64. 64. 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.
  65. 65. 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.
  66. 66. RESPOSTA OFFLINE
  67. 67. this.onfetch = function(event) { console.log(event.request.url); };
  68. 68. this.onfetch = function(event) { event.respondWith( new Response(‘conteúdo!') ); };
  69. 69. this.onfetch = function(event) { event.respondWith( caches.match(event.request) ); };
  70. 70. RESPOSTA DO CACHE
  71. 71. RESPOSTA DO CACHE E se não existir?
  72. 72. this.onfetch = function(event) { event.respondWith( caches.match(event.request).then(function(response){ }) ); };
  73. 73. this.onfetch = function(event) { event.respondWith( caches.match(event.request).then(function(response){ return response || event.default(); }) ); };
  74. 74. BAIXA NA REDE
  75. 75. BAIXA NA REDE E se estiver offline?
  76. 76. this.onfetch = function(event) { event.respondWith( caches.match(event.request).then(function(response){ return response || event.default(); }).catch(function() { return caches.match('/contato.html'); }) ); };
  77. 77. FALLBACK DE URLs
  78. 78. RESPOSTA programática & controlável
  79. 79. RESPOSTA programática & controlável Busco no cache.
  80. 80. RESPOSTA programática & controlável Busco no cache. Busco na rede.
  81. 81. RESPOSTA programática & controlável Busco no cache. Busco na rede. Devolvo fallback.
  82. 82. RESPOSTA programática & controlável Busco no cache. Busco na rede. Devolvo fallback. Construo resposta na mão.
  83. 83. 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.
  84. 84. ATUALIZAÇÕES
  85. 85. Mudo o worker.js
  86. 86. Mudo o worker.js Detecta na próxima navegação.
  87. 87. Mudo o worker.js Detecta na próxima navegação. Dispara instalação (oninstall) em background.
  88. 88. Mudo o worker.js Detecta na próxima navegação. Dispara instalação (oninstall) em background. (worker original ainda comanda a página)
  89. 89. Mudo o worker.js Detecta na próxima navegação. Dispara instalação (oninstall) em background. (worker original ainda comanda a página) Fecho a página.
  90. 90. Mudo o worker.js Detecta 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.
  91. 91. Mudo o worker.js Detecta 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).
  92. 92. Mudo o worker.js Detecta 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)
  93. 93. Mudo o worker.js Detecta 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.
  94. 94. 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' ]); }) ); };
  95. 95. this.onactivate = function(event) { event.waitUntil( caches.delete('aplicacao-v1') ); };
  96. 96. ATUALIZAÇÃO
  97. 97. ATUALIZAÇÃO Totalmente em background.
  98. 98. ATUALIZAÇÃO Totalmente em background. Não incomoda o usuário.
  99. 99. ATUALIZAÇÃO Totalmente em background. Não incomoda o usuário. Só troca no próximo acesso.
  100. 100. ATUALIZAÇÃO Totalmente em background. Não incomoda o usuário. Só troca no próximo acesso. Chrome-like.
  101. 101. detalhes dos SERVICE WORKERS
  102. 102. controle de escopo
  103. 103. navigator.serviceWorker.register('worker.js');
  104. 104. navigator.serviceWorker.register('worker.js', { scope: '/blog/' });
  105. 105. HTTPS only
  106. 106. tudo assíncrono
  107. 107. pode ser morto a qualquer momento
  108. 108. muito mais poderoso muito mais complicado
  109. 109. ainda não existe em nenhum browser
  110. 110. FUTURO FANTÁSTICO
  111. 111. BACKGROUND SYNC
  112. 112. postaTweet(texto);
  113. 113. try { postaTweet(texto); } catch (err) { }
  114. 114. try { postaTweet(texto); } catch (err) { salvaTweet(texto); registration.sync.register('envia-tweet'); }
  115. 115. postaTweet(texto).catch(function(){ });
  116. 116. postaTweet(texto).catch(function(){ salvaTweet(texto).then(function(){ }).then(function(){ }); });
  117. 117. postaTweet(texto).catch(function(){ return salvaTweet(texto).then(function(){ return navigator.serviceWorker.ready; }).then(function(registration){ return registration.sync.register('envia-tweet'); }); });
  118. 118. this.onsync = function (event) { if (event.id === 'envia-tweet') { } };
  119. 119. this.onsync = function (event) { if (event.id === 'envia-tweet') { event.waitUntil( carregaTweet().then(function(texto){ postaTweet(texto); }) ); } };
  120. 120. registration.sync.register('atualiza-inbox', { minInterval: 60 * 60 * 1000 });
  121. 121. PUSH NOTIFICATION
  122. 122. registration.pushRegistrationManager.register()
  123. 123. registration.pushRegistrationManager.register() .then(function(detalhes) { });
  124. 124. registration.pushRegistrationManager.register() .then(function(detalhes) { return avisaServidor(detalhes); });
  125. 125. this.onpush = function(event) { if (event.message.data == 'nova-mensagem') { } };
  126. 126. this.onpush = function(event) { if (event.message.data == 'nova-mensagem') { event.waitUntil( atualizaMensagens().then(function(){ }) ); } };
  127. 127. this.onpush = function(event) { if (event.message.data == 'nova-mensagem') { event.waitUntil( atualizaMensagens().then(function(){ new Notification("Chegou mensagem!"); }) ); } };
  128. 128. this.onnotificationclick = function(event) { };
  129. 129. this.onnotificationclick = function(event) { new ServiceWorkerClient('/mensagens.html'); };
  130. 130. GEOFENCING
  131. 131. ALARMES TEMPORAIS
  132. 132. SERVICE WORKERS hoje, depois do evento
  133. 133. estude Service Workers hoje. esse é o futuro.
  134. 134. brinque no Chrome Chrome Canary - chrome://flags #enable-experimental-web-platform-features
  135. 135. vote no status.modern.ie
  136. 136. use AppCache como fallback
  137. 137. offline como progressive enhancement if ('serviceWorker' in navigator) { }
  138. 138. pense offline first
  139. 139. OFFLINE WEB COM SERVICE WORKERS
  140. 140. OBRIGADO! sergiolopes.org @sergio_caelum

×