Desenvolvimento

28 abr, 2017

Como criar seu primeiro progressive web app do zero

Publicidade

No meu último artigo, fiz uma introdução aos Progressive Web Apps com as motivações de se criar um PWA ao invés de um app nativo e as suas principais características. Agora que você já sabe o porquê de desenvolver um Progressive Web App, vamos estudar e entender o como.

Sobre a aplicação

Antes de tudo, vamos conhecer a aplicação na qual vamos adicionar as técnicas necessárias para que ela seja transformada em um PWA. Quem trabalha com metologias ágeis já está acostumado com um ritual chamado Planning Poker. Em resumo, ele serve para que cada membro do time consiga fazer uma estimativa das tarefas a serem desenvolvidas.

O app construído faz exatamente isso.

Essa é a tela principal:

E essa é a tela após a seleção de uma das cartas:

Para visualizar a aplicação em produção, basta acessar este link e o código completo está aqui.

O arquivo manifest.json

O primeiro passo, e também o mais fácil, é adicionar o arquivo manifest.json.

O propósito do arquivo manifest é transformar uma aplicação web em algo instalável em um smartphone. Abaixo, segue um exemplo de um arquivo manifest.json válido:

{
  "name": "AgilePoker",
  "short_name": "AgilePoker",
  "theme_color": "#2a0044",
  "background_color": "#2a0044",
  "display": "standalone",
  "start_url": "/",
  "icons": [
    {
      "src": "images/icon-72x72.png",
      "sizes": "72x72",
      "type": "image/png"
    }
  ]
}

Pensei em ir campo a campo e mostrar o que cada um deles significa, mas é simplesmente mais fácil mostrar o resultado final em uma imagem:

Ou seja, a sua aplicação web agora pode abrir um splash screen exatamente igual aos apps nativos com pouquíssimo esforço.

Ah, lembrando que o arquivo deve ser importado no index.html, assim:

<link rel="manifest" href="/manifest.json">

Lembrando que você não precisa criar o arquivo manifest do zero. Existem algumas ferramentas gratuitas que fazem todo o trabalho para você. Recomendo principalmente essas duas:

Para conferir o manifest final da aplicação que construímos, basta entrar no GitHub do projeto.

Outras fontes boas sobre o arquivo manifest.json:

O que é um Service Worker?

Um problema bem comum que os usuários enfrentam desde o começo da web, e que vem aumentando com o uso dos dispositivos móveis, é a perda da conexão.

Nada é mais frustrante do que ter preenchido todos os dados para realizar uma compra e no último instante isso aparecer:

Os Services Workers vêm para tentar consertar, ou pelo menos minimizar, esse problema.

Mas vamos começar pela definição do SW: um Service Worker é um script que seu navegador executa em segundo plano, separado da página da Web, possibilitando recursos que não precisam de uma página da Web ou de interação do usuário.

Em resumo, o SW te dá a opção de manipular as requisições que são feitas por sua aplicação e com isso algo que nunca foi possível antes na web agora ficou extremamente fácil: o funcionamento offline.

Como criar um Service Worker

Agora que já sabemos o que é um SW e para que ele serve, vamos aprender a criar um do zero.

A primeira coisa que precisamos fazer é instalar o Service Worker. Durante a instalação, vamos adicionar ao cache todos os arquivos estáticos, que são gerados no build final:

var CACHE_NAME = 'static-v1';
 
self.addEventListener('install', function (event) {
  event.waitUntil(
    caches.open(CACHE_NAME).then(function (cache) {
      return cache.addAll([
        '/',
        '/index.html',
        '/styles.css',
        '/app.js',
        '/manifest.js',
        '/vendor.js',
      ]);
    })
  )
});

Repare que criamos uma variável chamada CACHE_NAME. Ela serve para “versionarmos” o cache. Ou seja, se coisas novas forem adicionadas ao código, simplesmente o static-v1 vira static-v2.

Agora precisamos fazer a ativação do Service Worker. Nesse passo, vamos atualizar o cache, se for necessário:

var CACHE_NAME = 'static-v1';
 
self.addEventListener('activate', function activator(event) {
  event.waitUntil(
    caches.keys().then(function (keys) {
      return Promise.all(keys
        .filter(function (key) {
          return key.indexOf(CACHE_NAME) !== 0;
        })
        .map(function (key) {
          return caches.delete(key);
        })
      );
    })
  );
});

Para finalizar, vamos usar o SW para interceptar requisições. A ideia é tentar pegar o que for solicitado do cache e, se ele não existir, aí sim vamos fazer um request:

self.addEventListener('fetch', function (event) {
  event.respondWith(
    caches.match(event.request).then(function (cachedResponse) {
      return cachedResponse || fetch(event.request);
    })
  );
});

Aqui está a versão final do SW que fizemos:

var CACHE_NAME = 'static-v1';
 
self.addEventListener('install', function (event) {
  event.waitUntil(
    caches.open(CACHE_NAME).then(function (cache) {
      return cache.addAll([
        '/',
        '/index.html',
        '/styles.css',
        '/app.js',
        '/manifest.js',
        '/vendor.js',
      ]);
    })
  )
});
 
self.addEventListener('activate', function activator(event) {
  event.waitUntil(
    caches.keys().then(function (keys) {
      return Promise.all(keys
        .filter(function (key) {
          return key.indexOf(CACHE_NAME) !== 0;
        })
        .map(function (key) {
          return caches.delete(key);
        })
      );
    })
  );
});
 
self.addEventListener('fetch', function (event) {
  event.respondWith(
    caches.match(event.request).then(function (cachedResponse) {
      return cachedResponse || fetch(event.request);
    })
  );
});

Lembrando que precisamos adicionar o SW que criamos no index.html, dessa forma:

<script>
  if ('serviceWorker' in navigator) {
    navigator.serviceWorker.register('/sw.js')
      .then(function () {
        console.log('service worker registered');
      })
      .catch(function () {
        console.warn('service worker failed');
      });
  }
</script>

E com isso, temos nosso Service Worker completo e a aplicação agora funciona em modo offline.

Para saber mais sobre os Service Workers:

Lighthouse

A forma fácil de saber se você está no caminho certo na construção do seu Progressive Web App é usar alguma ferramenta de inspeção. A que eu mais recomendo é o Lighthouse do Google.

Basta fazer o download da extensão para o Chrome, entrar no site que você deseja inspecionar e clicar no widget:

Depois, basta aguardar o resultado e visualizar o feedback do Google:

Conclusão

Pra fechar, com alguns simples passos conseguimos transformar nossa aplicação em um Progressive Web App. Agora são possíveis: funcionamento offline, adicionar o app à home screen do usuário etc.

Lembrando que a experiência do usuário no ambiente mobile pode ser, e geralmente é, bem diferente do ambiente desktop, então, sua aplicação tem que ser responsiva e adaptada para esse ambiente independente de ser um PWA ou não.

***

Agradecimentos especiais ao Flavio Nazario pelo trabalho de UX feito no AgilePoker.

Tem alguma dúvida ou perdeu algum passo? Só deixar abaixo o seu comentário. Até a próxima!

***

Este artigo foi originalmente publicado no Medium pessoal do autor. Confira aqui.

***

Artigo publicado também em: https://www.concretesolutions.com.br/2017/04/19/progressive-web-app-do-zero/