Progressive Web Apps em sites de várias origens

Desafios e soluções alternativas para criar Progressive Web Apps em sites de várias origens.

Demián Renzulli
Demián Renzulli

Contexto

No passado, havia algumas vantagens no uso de arquiteturas de várias origens, mas, para apps da Web progressivos, essa abordagem apresenta muitos desafios. Em particular, a política de mesma origem impõe restrições para compartilhar itens como service workers e caches, permissões e para alcançar uma experiência independente em várias origens. Este artigo descreve os usos positivos e negativos de várias origens e explica os desafios e soluções alternativas para criar apps da Web progressivos em sites com várias origens.

Usos bons e ruins de várias origens

Existem alguns motivos legítimos para os sites usarem uma arquitetura de várias origens, principalmente relacionados ao fornecimento de um conjunto independente de aplicativos da Web ou para criar experiências completamente isoladas umas das outras. Há também usos que devem ser evitados.

A boa notícia

Vamos conferir os motivos úteis primeiro:

  • Localização / idioma: use um domínio de nível superior de código de país para separar sites que serão veiculados em diferentes países (por exemplo, https://www.google.com.ar) ou subdomínios para dividir sites segmentados para diferentes locais (por exemplo, https://newyork.craigslist.org) ou oferecer conteúdo para um idioma específico (por exemplo, https://en.wikipedia.org).

  • Web apps independentes:use subdomínios diferentes para oferecer experiências com finalidades bastante diferentes do site na origem principal. Por exemplo, em um site de notícias, o app da Web de palavras cruzadas pode ser veiculado intencionalmente pelo https://crosswords.example.com, instalado e usado como um PWA independente, sem precisar compartilhar recursos ou funcionalidades com o site principal.

A má notícia

Se você não estiver fazendo nenhuma dessas coisas, é provável que o uso de uma arquitetura de várias origens seja uma desvantagem ao criar apps da Web progressivos.

Apesar disso, muitos sites continuam sendo estruturados dessa maneira sem um motivo específico ou por motivos "legados". Um exemplo é usar subdomínios para separar arbitrariamente partes de um site que deveriam fazer parte de uma experiência unificada.

Por exemplo, os seguintes padrões são altamente desencorajados:

  • Seções do site:separar diferentes seções de um site em subdomínios. Em sites de notícias, não é incomum encontrar a página inicial em: https://www.example.com, enquanto a seção de esportes fica em https://sports.example.com, a de política em https://politics.example.com e assim por diante. No caso de um site de e-commerce, use algo como https://category.example.com para categorias de produtos, https://product.example.com para páginas de produtos etc.

  • Fluxo de usuários:outra abordagem desencorajada é separar partes menores do site, como páginas para o login ou fluxos de compra em subdomínios. Por exemplo, usando https://login.example.com e https://checkout.example.com.

Para os casos em que não é possível migrar para uma única origem, confira a seguir uma lista de desafios e (quando possível) soluções alternativas que podem ser consideradas ao criar Progressive Web Apps.

Desafios e soluções alternativas para PWAs em diferentes origens

Ao criar um site em várias origens, é difícil oferecer uma experiência unificada de PWA, principalmente devido à política de mesma origem, que impõe várias restrições. Vamos conferir cada uma.

Service workers

A origem do URL do script do service worker precisa ser a mesma da página que chama register(). Isso significa que, por exemplo, uma página em https://www.example.com não pode chamar register() com um URL do service worker em https://section.example.com.

Outro ponto a ser considerado é que um service worker só pode controlar páginas hospedadas na origem e no caminho a que pertence. Isso significa que, se o service worker estiver hospedado em https://www.example.com, ele só poderá controlar URLs dessa origem (de acordo com o caminho definido no parâmetro de escopo), mas não controlará nenhuma página em outros subdomínios, como, por exemplo, aqueles em https://section.example.com.

Nesse caso, a única solução alternativa é usar vários service workers (um por origem).

Armazenamento em cache

O objeto Cache, o indexedDB e o localStorage também são restritos a uma única origem. Isso significa que não é possível acessar os caches que pertencem a https://www.example.com, por exemplo: https://www.section.example.com.

Confira algumas ações que você pode realizar para gerenciar os caches corretamente em cenários como este:

  • Aproveite o armazenamento em cache do navegador:sempre é recomendável usar as práticas recomendadas de armazenamento em cache do navegador tradicional. Essa técnica oferece o benefício adicional de reutilizar recursos em cache em várias origens, o que não pode ser feito com o cache do service worker. Para conferir as práticas recomendadas sobre como usar o cache HTTP com service workers, consulte esta postagem.

  • Mantenha a instalação do service worker leve:se você estiver mantendo vários service workers, evite fazer com que os usuários paguem um custo de instalação alto sempre que navegarem para uma nova origem. Em outras palavras, pré-cache apenas os recursos que são absolutamente necessários.

Permissões

As permissões também têm escopo para origens. Isso significa que, se um usuário conceder uma determinada permissão à origem https://section.example.com, ela não será transferida para outras origens, como https://www.example.com.

Como não há como compartilhar permissões entre origens, a única solução é solicitar permissão em cada subdomínio em que um determinado recurso é necessário (por exemplo, localização). Para recursos como push na Web, você pode manter um cookie para acompanhar se a permissão foi aceita pelo usuário em outro subdomínio, evitando que ela seja solicitada novamente.

Instalação

Para instalar um PWA, cada origem precisa ter o próprio manifesto com um start_url relativo a si mesmo. Isso significa que um usuário que receber a solicitação de instalação em uma determinada origem (por exemplo, https://section.example.com) não poderá instalar o PWA com um start_url em uma origem diferente (por exemplo, https://www.example.com). Em outras palavras, os usuários que receberem a solicitação de instalação em um subdomínio só poderão instalar PWAs para as subpáginas, não para o URL principal do app.

Também há o problema de que o mesmo usuário pode receber vários avisos de instalação ao navegar pelo site, se cada subdomínio atender aos critérios de instalação e solicitar que o usuário instale o PWA.

Para atenuar esse problema, verifique se a solicitação é mostrada apenas na origem principal. Quando um usuário visita um subdomínio que atende aos critérios de instalação:

  1. Detectar o evento beforeinstallprompt.
  2. Impedir que a solicitação apareça, chamando event.preventDefault().

Dessa forma, você garante que o aviso não seja mostrado em partes indesejadas do site, enquanto pode continuar mostrando, por exemplo, na origem principal (por exemplo, na página inicial).

Modo independente

Ao navegar em uma janela independente, o navegador vai se comportar de maneira diferente quando o usuário sair do escopo definido pelo manifesto da PWA. O comportamento depende da versão do navegador e do fornecedor. Por exemplo, as versões mais recentes do Chrome abrem uma guia personalizada do Chrome quando um usuário sai do escopo no modo independente.

Na maioria dos casos, não há solução para isso, mas uma solução alternativa pode ser aplicada a pequenas partes da experiência hospedadas em subdomínios (por exemplo, fluxos de trabalho de login):

  1. O novo URL, https://login.example.com, pode ser aberto em um iframe em tela cheia.
  2. Quando a tarefa for concluída no iframe (por exemplo, o processo de login), postMessage() poderá ser usado para transmitir as informações resultantes do iframe de volta à página mãe.
  3. Como etapa final, depois que a mensagem for recebida pela página principal, os listeners poderão ser cancelados e o iframe finalmente removido do DOM.

Conclusão

A política de mesma origem impõe muitas restrições a sites criados com várias origens que querem ter uma experiência coerente de PWA. Por isso, para oferecer a melhor experiência aos usuários, recomendamos que você não divida os sites em origens diferentes.

Para sites que já foram criados dessa forma, pode ser difícil fazer com que os PWA de várias origens funcionem corretamente, mas analisamos algumas soluções alternativas. Cada uma delas pode ter vantagens e desvantagens. Portanto, use seu bom senso ao decidir qual abordagem adotar no seu site.

Ao avaliar uma estratégia de longo prazo ou um redesign do site, considere migrar para uma única origem, a menos que haja um motivo importante para manter a arquitetura de várias origens.

Agradecemos muito pelas revisões técnicas e sugestões: Penny Mclachlan, Paul Covell, Dominick Ng, Alberto Medina, Pete LePage, Joe Medley, Cheney Tsai, Martin Schierle e Andre Bandarra.