Publicado em: 15 de junho de 2020
Ao jogar bingo de palavras-chave de Progressive Web App, é seguro apostar em "PWAs são apenas sites". A documentação de PWA da Microsoft concorda, nós dizemos isso, e os indicados ao PWA Frances Berriman e Alex Russell também. Sim, os PWAs são apenas sites, mas também são muito mais do que isso. Se feito da maneira certa, um PWA não vai parecer um site, mas um app real.
Mas o que significa parecer um app de verdade?
Por exemplo, o app Podcasts da Apple. Ele está disponível para macOS em computadores e para iOS (e iPadOS, respectivamente) em dispositivos móveis. Embora o Google Podcasts seja um aplicativo de mídia, as ideias principais que ilustro com a ajuda dele também se aplicam a outras categorias de apps.

Capaz de ser executado off-line
Pense nos aplicativos específicos da plataforma que você tem no smartphone ou computador. Uma coisa se destaca: você sempre pode usar esse recurso. No app Google Podcasts, mesmo off-line, sempre há algo para fazer ou ver. Quando não há conexão de rede, o app ainda abre. A seção Top Charts não mostra nenhum conteúdo. Em vez disso, ela volta para uma mensagem Não é possível se conectar agora com um botão Tentar novamente.

Faça isso na Web
O app Google Podcasts segue o chamado modelo de shell de app. Todo o conteúdo estático necessário para mostrar o app principal é armazenado em cache localmente, incluindo imagens decorativas, como os ícones do menu à esquerda e os ícones da interface do player principal. O conteúdo dinâmico, como os dados dos principais gráficos, só é carregado sob demanda. Se o carregamento falhar, um conteúdo alternativo armazenado em cache localmente estará disponível. Leia o artigo O modelo de app shell para saber como aplicar esse modelo arquitetônico ao seu app da Web.
Conteúdo off-line disponível e mídia reproduzível
Enquanto estiver off-line, no painel à esquerda, ainda será possível acessar a seção Downloads e reproduzir episódios de podcast baixados, que são exibidos com todos os metadados, incluindo arte e descrições.

Faça isso na Web
O conteúdo de mídia baixado anteriormente pode ser veiculado do cache, por exemplo, usando a receita Veicular áudio e vídeo em cache da biblioteca Workbox. Outros conteúdos podem sempre ser armazenados no cache ou no IndexedDB. Leia o artigo Armazenamento para a Web para saber todos os detalhes e quando usar cada tecnologia de armazenamento. Se você tiver dados que precisam ser armazenados de forma persistente sem o risco de serem excluídos quando a quantidade de memória disponível ficar baixa, use a API Persistent Storage.
Download proativo em segundo plano
Quando volto a ficar on-line, posso pesquisar conteúdo com uma consulta como http 203
. Quando decido me inscrever no resultado da pesquisa, o podcast HTTP 203, o episódio mais recente da série é baixado imediatamente, sem perguntas.

Faça isso na Web
O download de um episódio de podcast é uma operação que pode levar mais tempo. A API Background Fetch permite delegar downloads ao navegador, que cuida deles em segundo plano.
No Android, o navegador pode delegar esses downloads ainda mais ao sistema operacional, para que não precise ficar em execução continuamente. Quando o download for concluído, o service worker do app será ativado, e você poderá decidir o que fazer com a resposta.
Interagir e compartilhar com outros aplicativos
O app Podcasts se integra naturalmente a outros aplicativos. Por exemplo, quando clico com o botão direito em um episódio que gosto, posso compartilhar com outros apps no meu dispositivo, como o app Mensagens. Ele também se integra naturalmente à área de transferência do sistema. Posso clicar com o botão direito do mouse em qualquer episódio e copiar um link para ele.

Faça isso na Web
A API Web Share e a API Web Share Target permitem que seu app compartilhe e receba textos, arquivos e links de outros aplicativos no dispositivo. Embora ainda não seja possível para um web app adicionar itens ao menu de clique com o botão direito do mouse integrado ao sistema operacional, há muitas outras maneiras de vincular a outros apps no dispositivo. Com a API Async Clipboard, é possível ler e gravar programaticamente dados de texto e imagem (imagens PNG) na área de transferência do sistema. No Android, é possível usar a API Contact Picker para selecionar entradas do gerenciador de contatos do dispositivo. Se você oferecer um app específico da plataforma e um PWA, use a API Get Installed Related Apps para verificar se o app específico da plataforma está instalado. Nesse caso, não é necessário incentivar o usuário a instalar o PWA ou aceitar notificações push da Web.
Atualização de apps em segundo plano
Nas configurações do app Podcasts, posso configurar o download automático de novos episódios. Assim, não preciso nem pensar nisso, o conteúdo atualizado sempre vai estar lá. Mágica.

Faça isso na Web
A API Periodic Background Sync permite que seu app atualize o conteúdo regularmente em segundo plano sem precisar estar em execução. Isso significa que o novo conteúdo está disponível de forma proativa para que os usuários possam começar a explorar quando quiserem.
Estado sincronizado na nuvem
Minhas assinaturas são sincronizadas em todos os meus dispositivos. Em um mundo perfeito, não preciso me preocupar em manter minhas inscrições de podcasts sincronizadas manualmente. Da mesma forma, não preciso ter medo de que a memória do meu dispositivo móvel seja consumida por episódios que já ouvi no computador. O estado de reprodução é mantido sincronizado, e os episódios ouvidos são excluídos automaticamente.

Faça isso na Web
A sincronização de dados de estado do app é uma tarefa que pode ser delegada à API Background Sync. A operação de sincronização não precisa acontecer imediatamente, apenas eventualmente, e talvez até mesmo quando o usuário já tiver fechado o app de novo.
Controles de teclas de mídia de hardware
Quando estou ocupado com outro aplicativo, por exemplo, lendo uma página de notícias no navegador, ainda posso controlar o app Google Podcasts com as teclas de mídia no meu laptop. Não é preciso mudar para o app só para avançar ou voltar.

Faça isso na Web
As teclas de mídia são compatíveis com a API Media Session. Assim, os usuários podem usar as teclas de mídia de hardware em teclados físicos, fones de ouvido ou até mesmo controlar o web app com as teclas de mídia de software em smartwatches. Além disso, você pode usar um padrão de vibração quando o usuário buscar uma parte significativa do conteúdo, como passar os créditos iniciais ou o limite de um capítulo.
Multitarefas e atalho de app
É claro que posso fazer várias tarefas ao mesmo tempo e voltar para o app Podcasts de qualquer lugar. O app tem um ícone claramente distinguível que também posso colocar na área de trabalho ou no dock de aplicativos para que o Google Podcasts seja aberto imediatamente quando eu quiser.

Faça isso na Web
Os Progressive Web Apps para computadores e dispositivos móveis podem ser instalados na tela inicial, no menu Iniciar ou no dock de aplicativos. A instalação pode acontecer com base em uma solicitação proativa ou ser totalmente controlada pelo desenvolvedor do app. O artigo O que é preciso para ser instalável? aborda tudo o que você precisa saber. Ao fazer várias tarefas ao mesmo tempo, os PWAs aparecem independentes do navegador.
Ações rápidas no menu de contexto
As ações mais comuns do app, Pesquisar por novos conteúdos e Verificar novos episódios, estão disponíveis no menu de contexto do app no Dock. No menu Opções, também posso decidir abrir o app no momento do login.

Faça isso na Web
Ao especificar atalhos de ícones de apps no manifesto do app da Web do PWA, você pode registrar rotas rápidas para tarefas comuns que os usuários podem acessar diretamente no ícone do app. Em sistemas operacionais como o macOS, os usuários também podem clicar com o botão direito do mouse no ícone do app e definir que ele seja iniciado no momento do login. Há um trabalho em andamento em uma proposta para executar no login.
Atuar como app padrão
Outros aplicativos iOS e até mesmo sites ou e-mails podem se integrar ao app Podcasts usando o esquema de URL podcasts://
. Se eu clicar em um link como podcasts://podcasts.apple.com/podcast/the-css-podcast/id1042283903
no navegador, vou direto para o app Podcasts e posso decidir me inscrever ou ouvir o podcast.

Faça isso na Web
Ainda não é possível processar esquemas de URL totalmente personalizados, mas há uma proposta em andamento para processamento de protocolos de URL para PWAs. registerProtocolHandler()
com um prefixo de esquema web+
é a melhor alternativa.
Integração com o sistema de arquivos local
Talvez você não pense nisso imediatamente, mas o app Podcasts se integra naturalmente
ao sistema de arquivos local. Quando faço o download de um episódio de podcast para meu laptop, ele é
armazenado em ~/Library/Group Containers/243LU875E5.groups.com.apple.podcasts/Library/Cache
.
Ao contrário de ~/Documents
, por exemplo, esse diretório não foi criado para ser acessado diretamente por usuários comuns.
Outros mecanismos de armazenamento além de arquivos são referenciados na seção conteúdo off-line.

Faça isso na Web
A API File System Access permite que os desenvolvedores acessem o sistema de arquivos local do dispositivo. Você pode usar a API diretamente ou com a biblioteca de suporte browser-fs-access, que oferece um substituto transparente para navegadores que não têm suporte à API. Por motivos de segurança, os diretórios do sistema não podem ser acessados pela Web.
Aparência da plataforma
Há um recurso mais sutil que é autoevidente para um aplicativo iOS, como Podcasts. Nenhum dos rótulos de texto é selecionável, e todo o texto se mistura com a fonte do sistema da máquina. Além disso, minha escolha de tema de cores do sistema (como o modo escuro) é respeitada.


Faça isso na Web
Ao usar a propriedade CSS user-select
com o valor none
,
você pode proteger os elementos da interface contra seleção acidental.
No entanto, não abuse dessa propriedade para tornar o conteúdo do app não selecionável.
Ele só deve ser usado para elementos da interface, como textos de botões etc.
O valor system-ui
para a propriedade CSS font-family
permite
especificar a fonte padrão da interface do sistema a ser usada no app.
Por fim, o app pode obedecer à preferência de esquema de cores do usuário respeitando a escolha prefers-color-scheme
, com uma alternância do modo escuro
opcional para substituir essa preferência.
Outra decisão pode ser o que o navegador deve fazer ao atingir o limite de uma área de rolagem, por exemplo, para implementar um puxar para atualizar personalizado.
Isso é possível com a propriedade CSS overscroll-behavior
.
Barra de título personalizada
Ao olhar para a janela do app Podcasts, você percebe que ela não tem uma barra de título e uma barra de ferramentas integradas clássicas, como a janela do navegador Safari, mas uma experiência personalizada que parece uma barra lateral ancorada à janela principal do player.


Faça isso na Web
A personalização da barra de título tem disponibilidade limitada. Você pode (e deve) especificar as propriedades
display
e
theme-color
do manifesto do app da Web. Isso determina a aparência da janela do aplicativo e decide quais controles padrão do navegador devem ser mostrados, talvez nenhum.
Animações rápidas
As animações no app são rápidas e suaves no Podcasts. Por exemplo, quando abro o painel Notas do episódio à direita, ele desliza com elegância. Quando removo um episódio dos meus downloads, os outros sobem e ocupam o espaço da tela que foi liberado pelo episódio excluído.

Faça isso na Web
É possível criar animações eficientes na Web se você considerar várias práticas recomendadas descritas no artigo Animações e performance. As animações de rolagem, como as que são vistas em conteúdo paginado ou carrosséis de mídia, podem ser muito melhoradas com o recurso CSS Scroll Snap. Para controle total, use a API Web Animations.
Conteúdo exibido fora do app
O app Podcasts no iOS pode mostrar conteúdo em outros locais além do aplicativo em si, por exemplo, na visualização de widgets do sistema ou como uma sugestão da Siri.
As calls-to-action proativas e baseadas no uso que exigem apenas um toque para interagir podem aumentar muito a taxa de reengajamento de um app como o Google Podcasts.

Faça isso na Web
Use a API Content Index no aplicativo para informar ao navegador qual conteúdo do PWA está disponível off-line. Isso permite que o navegador exponha esse conteúdo fora do app principal. Ao marcar conteúdo interessante no seu app como adequado para reprodução de áudio speakable e usar marcação estruturada, você ajuda mecanismos de pesquisa e assistentes virtuais, como o Google Assistente, a apresentar suas ofertas de maneira ideal.
Widget de controle de mídia da tela de bloqueio
Quando um episódio de podcast está sendo reproduzido, o app Google Podcasts mostra um widget de controle na tela de bloqueio com metadados como a arte, o título e o nome do podcast.

Faça isso na Web
A API Media Session permite especificar metadados, como arte, títulos de músicas etc., que são exibidos na tela de bloqueio, em smartwatches ou em outros widgets de mídia no navegador.
Notificações push
As notificações push se tornaram um pouco irritantes na Web, embora os pedidos de notificação estejam muito mais silenciosos agora. Mas, se usadas corretamente, elas podem agregar muito valor. Por exemplo, o app Podcasts do iOS pode me notificar sobre novos episódios dos podcasts em que estou inscrito ou recomendar novos, além de me alertar sobre novos recursos do app.

Faça isso na Web
A API Push permite que seu app receba notificações push para que você possa avisar os usuários sobre eventos importantes no seu PWA. Para notificações que devem ser disparadas em um horário conhecido no futuro e que não exigem uma conexão de rede, use a API Notification Triggers.
Indicadores do ícone do app
Sempre que há novos episódios disponíveis de um dos podcasts em que me inscrevi, um selo de ícone do app aparece no ícone da tela inicial do Google Podcasts, incentivando-me a interagir com o app de uma forma não intrusiva.

Faça isso na Web
É possível definir indicadores de ícone de app com a API Badging. Isso é especialmente útil quando o PWA tem uma noção de itens "não lidos" ou quando você precisa de uma maneira de chamar a atenção do usuário de volta para o app sem incomodar.
A reprodução de mídia tem precedência sobre as configurações de economia de energia
Quando a mídia do podcast está sendo reproduzida, a tela pode ser desligada, mas o sistema não entra no modo de espera. Os apps também podem manter a tela ativada, por exemplo, para mostrar letras de músicas ou legendas.

Faça isso na Web
Use a API Screen Wake Lock para evitar que a tela seja desligada. A reprodução de mídia na Web impede automaticamente que o sistema entre no modo de espera.
Descoberta de apps em uma app store
Embora o app Podcasts faça parte da experiência de desktop do macOS, no iOS ele precisa
ser instalado na App Store. Uma pesquisa rápida por podcast
, podcasts
ou apple podcasts
mostra o app imediatamente na App Store.

Faça isso na Web
Embora a Apple não permita PWAs na App Store, com o Android, você pode
enviar seu PWA encapsulado em uma
Atividade Confiável na Web.
O script bubblewrap
facilita essa operação. Esse script também é o que internamente
alimenta o recurso de exportação de apps Android do
PWABuilder, que você pode usar sem precisar acessar a linha de comando.
Resumo do recurso
Essa tabela mostra uma visão geral compacta de todos os recursos e fornece uma lista de recursos úteis para implementá-los na Web.
Conclusão
Os PWAs evoluíram muito desde a introdução em 2015. No contexto do Projeto Fugu 🐡, a equipe do Chromium de várias empresas está trabalhando para fechar as últimas lacunas restantes. Seguindo apenas algumas das dicas que compartilhamos, você pode se aproximar dessa sensação de app e fazer com que os usuários esqueçam que estão lidando com "apenas um site". Afinal, a maioria dos usuários não se importa com a forma como o app é criado (e por que se importariam?), desde que pareça um app real.
Agradecimentos
Este documento foi revisado por Kayce Basques, Joe Medley, Joshua Bell, Dion Almaer, Ade Oshineye, Pete LePage, Sam Thorogood, Reilly Grant, e Jeffrey Yasskin.