O slideshow foi denunciado.
Utilizamos seu perfil e dados de atividades no LinkedIn para personalizar e exibir anúncios mais relevantes. Altere suas preferências de anúncios quando desejar.

Offline Web com Service Workers - Sérgio Lopes

4.869 visualizações

Publicada em

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.

Publicada em: Tecnologia

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

×