ServiceWorkers – e o futuro das aplicações no seu browser



ServiceWorkers – e o futuro das aplicações no seu browser

0 0


service-worker-tdc-sp-2015

Palestra no TDC SP 2015

On Github eduardojmatos / service-worker-tdc-sp-2015

ServiceWorkers

e o futuro das aplicações no seu browser

Eduardo Matos

@eduardojmatos

Soluções de comunicação que aproximam médicos e pacientes

O que é um worker?

Primeira definição de Worker surgiu com o WebWorkers http://www.html5rocks.com/en/tutorials/workers/basics/

Browser executando tarefas sem bloquear a interface

Resumindo: scripts rodando em paralelo à pagina

EX: tarefas que exigem alto processamento

            // main script
var worker = new Worker('worker.js');

worker.addEventListener('message', function(e) {
  console.log('Worker diz: ', e.data);
}, false);

worker.postMessage('Oi, eu sou o Worker!');

// worker.js
self.addEventListener('message', function(e) {
  self.postMessage(e.data);
}, false);
          

Regras comuns de um Worker

  • Não acessa o DOM
  • Não acessa o window
  • Não acessa o document
  • Acessa o navigator
  • Acessa o location (ready-only)

E o ServiceWorkers?

  • Usa o mesmo conceito do WebWorker de isolar execução de um script
  • Controla programaticamente o cache da sua aplicação
  • Serve como um proxy
  • BackgroundSync (!)
  • [breve] Push Notifications (!!)
  • [futuramente] Geofencing (!!!)
  • [futuramente] Bluetooth (!!!!)

Offline control

Vai Application Cache!

A forma de cachear arquivos parecia simples...

http://diveintohtml5.info/offline.html
            < html manifest="offline.appcache">
          
            CACHE MANIFEST
assets/6/script/mainmin.js
assets/6/style/mainmin.css
assets/6/style/fonts/pro.ttf
assets/6/style/imgs/sprites1.png
          

AppCache is a douchebag!

http://alistapart.com/article/application-cache-is-a-douchebag http://sergiolopes.org/palestra-appcache-html5-offline http://eduardomatos.me/appcache-manifest-e-serviceworker-as-partes-boas-e-ruins
  • Os arquivos sempre virão do ApplicationCache mesmo se você estiver online
  • O AppCache só atualiza o conteúdo do manifesto se ele mesmo for atualizado
  • Se você colocar a URL no manifesto ele nunca mais vai ser atualizado
  • Se eu não definir um fallback de NETWORK nada que está fora do manifesto é carregado
  • Ele cacheia a página que contém o manifesto mesmo que eu não queira
  • Se houver algum item listado que não foi encontrado (404, 500), o cache todo é descartado

E como ServiceWorker melhora isso?

            https://meu.server.com/data/posts.json
https://meu.server.com/assets/application.css
https://meu.server.com/assets/application.js
https://meu.server.com/assets/image.jpeg
          
            // main script
navigator.serviceWorker.register("/js/sw_cache.js").then(
  function ( serviceWorker ) {
      console.log("ServiceWorkers instalado com sucesso.");
  },
  function ( error ) {
      console.error("Ops.. não rolou a instalação do ServiceWorkers", error);
  });
          

Cacheando seus assets

            // assets/sw_cache.js
self.addEventListener('install', function(event) {
  var urlsToPrefetch = [
    'https://www.chromium.org/_/rsrc/1302286216006/config/customLogo.gif'
  ];
  event.waitUntil(
    caches.open(CURRENT_CACHES['prefetch']).then(function(cache) {
      return cache.addAll(urlsToPrefetch.map(function(urlToPrefetch) {
          return new Request(urlToPrefetch, {mode: 'no-cors'});
        })
      ).then(function() {
        console.log('All resources fetched and cached.');
      });
    }).catch(function(error) {
      console.error('Pre-fetching failed:', error);
    })

  );
})
          
https://github.com/GoogleChrome/samples/tree/gh-pages/service-worker

Interceptando requests

              // assets/service-worker.js
var base = "https://meu.server.com";

var data_url = new URL("/data/posts.json", base) + "";

self.addEventListener("fetch", function(e) {
  var url = e.request.url;
  console.log(url);
  if (url == data_url) {
    e.respondWith(
      new Response(JSON.stringify({
        posts: { /* ... */ }
      }), {
        headers: { 'Content-Type': 'application/json' },
        status: 200
      })
    );
  }
});
            

Request + Cache

            // assets/worker.js
self.version = 2;

var base = "https://meu.server.com"
var data_url = new URL("/data/posts.json", base) + "";

self.addEventListener("fetch",
    function ( e ) {
        if (e.request.url == data_url) {
          e.respondWith(
            caches.match( e.request )
                .catch( function () {
                    return e.default;
                })
                .catch( function () {
                    return caches.match("/data/posts_fallback.json");
                })
          );
        }
    }
);
          

Exemplo de ServiceWorkers

https://jakearchibald.github.io/trained-to-thrill/

E a segurança disso?

  • Funciona apenas com https
  • Escopo por domains

BACKGROUND SYNC

Ainda muito recente

              navigator.serviceWorker.ready.then(function (sw) {
  // Returns a Promise
  navigator.sync.register(
    "my_data_sync",
    {
      minInterval: 86400 * 1000,       // ms, default: heuristic
      repeating: true,                 // default: false
      data: '',                        // default: empty string
      description: '',                 // default: empty string
      lang: '',                        // default: document lang
      dir: ''                          // default: document dir
    }
  ).then(function() { // Success
       // No resolved value
       // Success, sync is now registered
     },
     function() { // Failure
       // If no SW registration
       // User/UA denied permission
       // Sync id already registered
     });
});
            
              // assets/service-worker.js
  self.onsync = function(event) {
    var data = JSON.parse(event.data);

    if (event.id === "my_data_sync") {
      if (data.whatever === "foo") {
        // rejection is indication that the UA should try
        // later (especially when network is ok)
        event.waitUntil(doAsyncStuff());
      }
    } else {
      // Garbage collect unknown syncs (perhaps from older pages).
      navigator.sync.unregister(event.id);
    }
  };
            

Geofencing

Nem a spec foi definida.

Bluetooth

Spec ainda engatinhando

https://github.com/WebBluetoothCG/web-bluetooth http://www.w3.org/community/web-bluetooth

Onde funciona?

https://jakearchibald.github.io/isserviceworkerready/

Porque esse hype todo?

  • JavaScript chegando no app nativo
  • Evolução e maior controle das aplicações
  • Acesso a funcionalidades do sistema do usuário (bluetooth, push notifications...)

Obrigado!

link da palestra: http://bit.ly/service-workers-tdc-sp

meu twitter: @eduardojmatos

fontes: http://bit.ly/serviceworkers-links