Deixe o PWA mais parecido com um app

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.

Um iPhone e um MacBook lado a lado, ambos executando o app Podcasts.
Apple Podcasts no iPhone e no macOS (Fonte).

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.

O app Podcasts mostra uma mensagem informando que "não é possível se conectar agora" quando não há conexão de rede disponível.

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.

App Podcasts com um episódio baixado de um podcast em reprodução.
Os episódios de podcast baixados podem ser reproduzidos mesmo sem rede.

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.

O app Podcasts baixa o último episódio de um podcast imediatamente após a inscrição.
Depois de se inscrever em um podcast, o episódio mais recente é baixado imediatamente.

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.

O menu de contexto do app Podcasts invocado em um episódio com a opção "Compartilhar episódio → Mensagens" selecionada.
Compartilhar um episódio de podcast no app Mensagens.

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.

O Google Podcasts está configurado para atualizar seu feed com novos episódios de podcast a cada hora.

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.

O menu de configurações do app Google Podcasts na seção "Avançado", em que a opção "Sincronizar inscrições em vários dispositivos" está ativada. O estado é sincronizado na nuvem.

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.

Teclado Magic do Apple MacBook Pro com teclas de mídia anotadas.
As teclas de mídia permitem controlar o app Podcasts.

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.

O alternador de tarefas do macOS com vários ícones de apps para escolher, um deles o app Podcasts.
Voltar para o app Podcasts com a multitarefa.

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.

Menu de contexto do ícone do app Podcasts mostrando as opções "Pesquisar" e "Verificar novos episódios".
As ações rápidas ficam disponíveis imediatamente no ícone do app.

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.

O navegador Chrome mostrando uma caixa de diálogo de confirmação perguntando ao usuário se ele quer abrir o app Podcasts.
O app Podcasts pode ser aberto diretamente no navegador.

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.

O Finder do macOS navegou até o diretório do sistema do app Podcasts.
Os episódios de podcast são armazenados em uma pasta especial do app do sistema.

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.

O app Podcasts no modo escuro.
O app Podcasts é compatível com o modo claro e escuro.
O app Podcasts no modo claro.
O app usa a fonte padrão do sistema.

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.

A barra de ferramentas e a barra de blocos integradas do navegador Safari.
Barras de título personalizadas do Safari e do app Podcasts.

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.

O app Podcasts com o painel "Notas do episódio" aberto.
As animações no app, como ao abrir um gaveta, são rápidas.

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.

A visualização do widget do iOS mostra o app Podcasts sugerindo um novo episódio.

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.

Widget de reprodução de mídia do iOS na tela de bloqueio mostrando um episódio de podcast com metadados avançados.
A mídia em reprodução no app pode ser controlada na tela de bloqueio.

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.

App Podcasts do iOS na tela de configurações "Notificações" mostrando a opção de ativar/desativar notificações de "Novos episódios".
Os apps podem enviar notificações push para informar o usuário sobre novos conteúdos.

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.

Tela de configurações do iOS mostrando a chave "Badges" ativada.
Os selos são uma maneira sutil de os aplicativos informarem aos usuários sobre novos conteúdos.

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.

Preferências do macOS na seção "Economia de energia".
Os apps podem manter a tela ativada.

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.

A pesquisa "podcasts" na App Store do iOS mostra o app Podcasts.
Os usuários aprenderam a descobrir apps nas app stores.

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.

Recurso Recursos úteis para fazer isso na Web
Capacidade de execução off-line
Conteúdo off-line disponível e mídia reproduzível
Download proativo em segundo plano
Compartilhamento e interação com outros aplicativos
Atualização de apps em segundo plano
Estado sincronizado na nuvem
Controles de teclas de mídia de hardware
Multitarefas e atalho de app
Ações rápidas no menu de contexto
Agir como app padrão
Integração do sistema de arquivos local
Aparência da plataforma
Barra de título personalizada
Animações rápidas
Conteúdo exibido fora do app
Widget de controle de mídia da tela de bloqueio
Notificações push
Notificações no ícone do app
A reprodução de mídia substitui as configurações de economia de energia
Descoberta de apps em uma app store

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.