Compartilhar via


PWA (Aplicativo Web Progressivo) do ASP.NET Core Blazor

Observação

Esta não é a versão mais recente deste artigo. Para informações sobre a versão vigente, confira a Versão do .NET 8 deste artigo.

Aviso

Esta versão do ASP.NET Core não tem mais suporte. Para obter mais informações, confira .NET e a Política de Suporte do .NET Core. Para informações sobre a versão vigente, confira a Versão do .NET 8 deste artigo.

Importante

Essas informações relacionam-se ao produto de pré-lançamento, que poderá ser substancialmente modificado antes do lançamento comercial. A Microsoft não oferece nenhuma garantia, explícita ou implícita, quanto às informações fornecidas aqui.

Para informações sobre a versão vigente, confira a Versão do .NET 8 deste artigo.

Um PWA Blazor (Aplicativo Web Progressivo) é um SPA (aplicativo de página única) que usa APIs de navegador modernas e funcionalidades para se comportar como um aplicativo da área de trabalho.

Blazor WebAssembly é uma plataforma de aplicativo Web do lado do cliente baseada em padrões, portanto, ela pode usar qualquer API do navegador, incluindo APIs de PWA necessárias para os seguintes recursos:

  • Trabalhar offline e carregar instantaneamente, independentemente da velocidade da rede.
  • Em execução em sua própria janela de aplicativo, não apenas em uma janela do navegador.
  • Sendo iniciado no menu Iniciar, encaixe ou tela home do sistema operacional do host.
  • Receber notificações por push de um servidor de back-end, mesmo enquanto o usuário não estiver usando o aplicativo.
  • Atualização automática em segundo plano.

A palavra progressiva é usada para descrever esses aplicativos porque:

  • Um usuário pode primeiro descobrir e usar o aplicativo em seu navegador da Web como qualquer outro SPA.
  • Posteriormente, o usuário progride para instalá-lo em seu sistema operacional e habilitar notificações por push.

Criar um projeto com base no modelo PWA

Ao criar um novo Aplicativo Blazor WebAssembly, marque a caixa de seleção Aplicativo Web Progressivo.

Opcionalmente, o PWA pode ser configurado para um aplicativo criado a partir do modelo de projeto hospedadoBlazor WebAssembly do ASP.NET Core. O cenário do PWA é independente do modelo de hospedagem.

Converter um aplicativo Blazor WebAssembly existente em um PWA

Converta um aplicativo existente Blazor WebAssembly em um PWA seguindo as diretrizes desta seção.

No arquivo de projeto do aplicativo:

  • Adicione a seguinte propriedade ServiceWorkerAssetsManifest a um PropertyGroup:

      ...
      <ServiceWorkerAssetsManifest>service-worker-assets.js</ServiceWorkerAssetsManifest>
    </PropertyGroup>
    
  • Adicione o seguinte item ServiceWorker a um ItemGroup:

    <ItemGroup>
      <ServiceWorker Include="wwwroot\service-worker.js" 
        PublishedContent="wwwroot\service-worker.published.js" />
    </ItemGroup>
    

Para obter ativos estáticos, use uma das seguintes abordagens:

  • Crie um novo projeto PWA separado com o comando dotnet new em um shell de comando:

    dotnet new blazorwasm -o MyBlazorPwa --pwa
    

    No comando anterior, a opção -o|--output cria uma nova pasta para o aplicativo chamado MyBlazorPwa.

    Se você não estiver convertendo um aplicativo para a versão mais recente, passe a opção -f|--framework. O exemplo a seguir cria o aplicativo para ASP.NET Core versão 5.0:

    dotnet new blazorwasm -o MyBlazorPwa --pwa -f net5.0
    
  • Navegue até o repositório GitHub ASP.NET Principal na URL a seguir, que vincula à origem e aos ativos main de referência de branch. Selecione a versão com a qual você está trabalhando na lista suspensa Alternar branches ou marcas que se aplica ao seu aplicativo.

    Pasta wwwroot de modelo do projeto Blazor WebAssembly (branch main do repositório dotnet/aspnetcore do GitHub)

    Observação

    Os links de documentação para a fonte de referência do .NET geralmente carregam o branch padrão do repositório, que representa o desenvolvimento atual da próxima versão do .NET. Para selecionar uma marca para uma versão específica, use a lista suspensa para Alternar branches ou marcas. Para saber mais, confira Como selecionar uma marca de versão do código-fonte do ASP.NET Core (dotnet/AspNetCore.Docs #26205).

    Na pasta de origem wwwroot no aplicativo que você criou ou nos ativos de referência no dotnet/aspnetcore repositório GitHub, copie os seguintes arquivos na pasta do wwwroot aplicativo:

    • icon-192.png
    • icon-512.png
    • manifest.webmanifest
    • service-worker.js
    • service-worker.published.js

No arquivo wwwroot/index.html do aplicativo:

  • Adicione elementos <link> para o manifesto e o ícone do aplicativo:

    <link href="manifest.webmanifest" rel="manifest" />
    <link rel="apple-touch-icon" sizes="512x512" href="icon-512.png" />
    <link rel="apple-touch-icon" sizes="192x192" href="icon-192.png" />
    
  • Navegue até o repositório GitHub do ASP.NET Core na URL a seguir, que é vinculada à origem e aos ativos de referência do branch release/7.0. Se você estiver usando uma versão do ASP.NET Core posterior à 7.0, altere o seletor de versão do documento para ver as diretrizes atualizadas para esta seção. Selecione a versão com a qual você está trabalhando na lista suspensa Alternar branches ou marcas que se aplica ao seu aplicativo.

    Pasta wwwroot de modelo do projeto Blazor WebAssembly (branch release/7.0 do repositório dotnet/aspnetcore do GitHub)

    Observação

    Os links de documentação para a fonte de referência do .NET geralmente carregam o branch padrão do repositório, que representa o desenvolvimento atual da próxima versão do .NET. Para selecionar uma marca para uma versão específica, use a lista suspensa para Alternar branches ou marcas. Para saber mais, confira Como selecionar uma marca de versão do código-fonte do ASP.NET Core (dotnet/AspNetCore.Docs #26205).

    Na pasta de origem wwwroot no aplicativo que você criou ou nos ativos de referência no dotnet/aspnetcore repositório GitHub, copie os seguintes arquivos na pasta do wwwroot aplicativo:

    • favicon.png
    • icon-512.png
    • manifest.json
    • service-worker.js
    • service-worker.published.js

No arquivo wwwroot/index.html do aplicativo:

  • Adicione elementos <link> para o manifesto e o ícone do aplicativo:

    <link href="manifest.json" rel="manifest" />
    <link rel="apple-touch-icon" sizes="512x512" href="icon-512.png" />
    
  • Adicione a seguinte marca <script> dentro da marca </body> de fechamento imediatamente após a marca de scriptblazor.webassembly.js:

        ...
        <script>navigator.serviceWorker.register('service-worker.js');</script>
    </body>
    

Instalação e manifesto do aplicativo

Ao visitar um aplicativo criado usando o modelo do PWA, os usuários têm a opção de instalar o aplicativo no menu Iniciar, no encaixe ou na tela home do sistema operacional. A maneira como essa opção é apresentada depende do navegador do usuário. Ao usar navegadores baseados em Chromium da área de trabalho, como Edge ou Chrome, um botão Adicionar aparece na barra de URL. Depois que o usuário seleciona o botão Adicionar , ele recebe uma caixa de diálogo de confirmação:

A caixa de diálogo de confirmação no Google Chrome apresenta ao usuário um botão Instalar para o aplicativo

No iOS, os visitantes podem instalar o PWA usando o botão Compartilhar do Safari e a opção Adicionar à tela. No Chrome para Android, os usuários devem selecionar o botão Menu no canto superior direito, seguido por Adicionar à tela Home.

Depois de instalado, o aplicativo aparece em sua própria janela sem uma barra de endereços:

O aplicativo

Para personalizar o título, o esquema de cores, o ícone ou outros detalhes da janela, consulte o arquivo manifest.json no diretório wwwroot do projeto. O esquema desse arquivo é definido pelos padrões da Web. Para obter mais informações, consulte documentos da Web do MDN: Manifesto do Aplicativo Web.

Suporte offline

Os aplicativos criados usando a opção de modelo PWA têm suporte para execução offline. Um usuário deve primeiro visitar o aplicativo enquanto estiver online. O navegador baixa e armazena em cache automaticamente todos os recursos necessários para operar offline.

Importante

O suporte ao desenvolvimento interferiria no ciclo de desenvolvimento usual de fazer alterações e testá-las. Portanto, o suporte offline só está habilitado para aplicativos publicados.

Aviso

Se você pretende distribuir um PWA habilitado para offline, há vários avisos e advertências importantes. Esses cenários são inerentes a PWAs offline e não são específicos para Blazor. Certifique-se de ler e entender essas ressalvas antes de fazer suposições sobre como seu aplicativo habilitado para offline funciona.

Para ver como funciona o suporte offline:

  1. Publique o aplicativo. Para obter mais informações, confira Hospedar e implantar o ASP.NET CoreBlazor.

  2. Implante o aplicativo em um servidor que dê suporte a HTTPS e acesse o aplicativo em um navegador em seu endereço HTTPS seguro.

  3. Abra as ferramentas de desenvolvimento do navegador e verifique se um Service Worker está registrado para o host na guia Aplicativo:

    A guia

  4. Recarregue a página e examine a guia Rede. Service Worker ou cache de memória são listados como as fontes para todos os ativos da página:

    A guia

  5. Para verificar se o navegador não depende do acesso à rede para carregar o aplicativo, também:

    • Desligue o servidor Web e veja como o aplicativo continua funcionando normalmente, o que inclui recarregamentos de página. Da mesma forma, o aplicativo continua funcionando normalmente quando há uma conexão de rede lenta.
    • Instrua o navegador a simular o modo offline na guia Rede:

    A guia

O suporte offline usando um trabalho de serviço é um padrão da Web, não específico para Blazor. Para obter mais informações sobre os funcionários do serviço, consulte Documentos web MDN: API do Service Worker. Para saber mais sobre padrões de uso comuns para service workers, consulte Google Web: O Ciclo de Vida do Service Worker.

O modelo PWA do Blazor produz dois arquivos de trabalho de serviço:

  • wwwroot/service-worker.js, que é usado durante o desenvolvimento.
  • wwwroot/service-worker.published.js, que é usado após a publicação do aplicativo.

Para compartilhar a lógica entre os dois arquivos de trabalho de serviço, considere a seguinte abordagem:

  • Adicione um terceiro arquivo JavaScript para manter a lógica comum.
  • Use self.importScripts para carregar a lógica comum em ambos os arquivos de trabalho do serviço.

Estratégia de busca de primeiro cache

O service worker service-worker.published.js interno resolve solicitações usando uma estratégia de primeiro cache. Isso significa que o trabalho de serviço prefere retornar conteúdo armazenado em cache, independentemente de o usuário ter acesso à rede ou conteúdo mais recente disponível no servidor.

A estratégia de primeiro cache é valiosa porque:

  • Ele garante a confiabilidade. O acesso à rede não é um estado booliano. Um usuário não está simplesmente online ou offline:

    • O dispositivo do usuário pode assumir que está online, mas a rede pode ser tão lenta quanto ser impraticável de esperar.
    • A rede pode retornar resultados inválidos para determinadas URLs, como quando há um portal WIFI cativo que está bloqueando ou redirecionando determinadas solicitações no momento.

    É por isso que a API navigator.onLine do navegador não é confiável e não deve depender.

  • Ele garante a correção. Ao criar um cache de recursos offline, o trabalhador do serviço usa o hash de conteúdo para garantir que ele tenha buscado uma instantâneo completa e autoconsistente de recursos em um único instante no tempo. Esse cache é então usado como uma unidade atômica. Não adianta pedir recursos mais recentes à rede, pois as únicas versões necessárias são as já armazenadas em cache. Qualquer outra coisa corre o risco de inconsistência e incompatibilidade (por exemplo, tentar usar versões de assemblies .NET que não foram compilados juntos).

Se você precisar impedir que o navegador busque service-worker-assets.js seu cache HTTP, por exemplo, para resolve integridade temporária marcar falhas ao implantar uma nova versão do trabalho de serviço, atualize o registro do service worker em wwwroot/index.html com definido como updateViaCache 'none':

<script>
  navigator.serviceWorker.register('/service-worker.js', {updateViaCache: 'none'});
</script>

Atualizações em segundo plano

Como um modelo mental, você pode pensar em um PWA offline-first como se comportando como um aplicativo móvel que pode ser instalado. O aplicativo é iniciado imediatamente, independentemente da conectividade de rede, mas a lógica do aplicativo instalada vem de uma instantâneo pontual que pode não ser a versão mais recente.

O modelo PWA Blazor produz aplicativos que tentam se atualizar automaticamente em segundo plano sempre que o usuário visita e tem uma conexão de rede funcional. A maneira como isso funciona é a seguinte:

  • Durante a compilação, o projeto gera um manifesto de ativos do trabalho de serviço, com o nome service-worker-assets.js. O manifesto lista todos os recursos estáticos que o aplicativo requer para funcionar offline, como assemblies .NET, arquivos JavaScript e CSS, incluindo seus hashes de conteúdo. A lista de recursos é carregada pelo trabalho de serviço para que ele saiba quais recursos armazenar em cache.
  • Sempre que o usuário visita o aplicativo, o navegador solicita novamente service-worker.js e service-worker-assets.js em segundo plano. Os arquivos são comparados byte por byte com o trabalho de serviço instalado existente. Se o servidor retornar conteúdo alterado para qualquer um desses arquivos, o trabalhador do serviço tentará instalar uma nova versão de si mesmo.
  • Ao instalar uma nova versão de si mesmo, o service worker cria um cache novo e separado para recursos offline e começa a preencher o cache com recursos listados em service-worker-assets.js. Essa lógica é implementada na função onInstall dentro service-worker.published.js.
  • O processo é concluído com êxito quando todos os recursos são carregados sem erro e todos os hashes de conteúdo correspondem. Se tiver êxito, o novo service worker entrará em um estado de espera para ativação . Assim que o usuário fecha o aplicativo (sem guias ou janelas de aplicativo restantes), o novo trabalho de serviço fica ativo e é usado para visitas subsequentes ao aplicativo. O antigo service worker e seu cache são excluídos.
  • Se o processo não for concluído com êxito, a nova instância de trabalho de serviço será descartada. O processo de atualização é tentado novamente na próxima visita do usuário, quando esperamos que o cliente tenha uma conexão de rede melhor que possa concluir as solicitações.

Personalize esse processo editando a lógica do service worker. Nenhum dos comportamentos anteriores é específico, Blazor mas é apenas a experiência padrão fornecida pela opção de modelo PWA. Para obter mais informações, consulte MDN Web docs: API do Service Worker.

Como as solicitações são resolvidas

Conforme descrito na seção Estratégia de busca do cache primeiro, o service worker padrão usa uma estratégia de cache primeiro, o que significa que ele tenta servir conteúdo armazenado em cache quando disponível. Se não houver conteúdo armazenado em cache para uma determinada URL, por exemplo, ao solicitar dados de uma API de back-end, o trabalhador do serviço retornará em uma solicitação de rede regular. A solicitação de rede terá êxito se o servidor estiver acessível. Essa lógica é implementada na onFetch da função dentro do service-worker.published.js.

Se os componentes Razor do aplicativo dependem da solicitação de dados de APIs de back-end e você deseja fornecer uma experiência amigável do usuário para solicitações com falha devido à indisponibilidade da rede, implemente a lógica dentro dos componentes do aplicativo. Por exemplo, use try/catch em torno de solicitações HttpClient.

Dar suporte a páginas renderizadas pelo servidor

Considere o que acontece quando o usuário navega pela primeira vez para uma URL, como /counter ou qualquer outro link profundo no aplicativo. Nesses casos, você não deseja retornar o conteúdo armazenado em cache como /counter, mas, em vez disso, precisa do navegador para carregar o conteúdo armazenado em cache para /index.html iniciar seu aplicativo Blazor WebAssembly. Essas solicitações iniciais são conhecidas como solicitações de navegação, em vez de:

  • Solicitações subresource de imagens, folhas de estilos ou outros arquivos.
  • Solicitações fetch/XHR de dados de API.

O service worker padrão contém lógica de caso especial para solicitações de navegação. O service worker resolve as solicitações retornando o conteúdo armazenado em cache para /index.html, independentemente da URL solicitada. Essa lógica é implementada na função onFetch dentro do service-worker.published.js.

Se seu aplicativo tiver determinadas URLs que devem retornar HTML renderizado pelo servidor e não servir /index.html do cache, você precisará editar a lógica em seu trabalho de serviço. Se todas as URLs que contêm /Identity/ precisarem ser tratadas como solicitações somente online regulares para o servidor, modifique a lógica de service-worker.published.js onFetch. Localize o seguinte código:

const shouldServeIndexHtml = event.request.mode === 'navigate';

Altere o código para o seguinte:

const shouldServeIndexHtml = event.request.mode === 'navigate'
  && !event.request.url.includes('/Identity/');

Se você não fizer isso, independentemente da conectividade de rede, o service worker interceptará solicitações para essas URLs e as resolverá usando /index.html.

Adicione pontos de extremidade adicionais para provedores de autenticação externa ao marcar. No exemplo a seguir, /signin-google para a autenticação do Google, é adicionado ao marcar:

const shouldServeIndexHtml = event.request.mode === 'navigate'
  && !event.request.url.includes('/Identity/')
  && !event.request.url.includes('/signin-google');

Nenhuma ação é necessária para o ambiente Development, em que o conteúdo sempre é buscado da rede.

Controlar o cache de ativos

Se o projeto definir a propriedade MSBuild ServiceWorkerAssetsManifest, as ferramentas de build do Blazor gerarão um manifesto de ativos de trabalho de serviço com o nome especificado. O modelo PWA padrão produz um arquivo de projeto que contém a seguinte propriedade:

<ServiceWorkerAssetsManifest>service-worker-assets.js</ServiceWorkerAssetsManifest>

O arquivo é colocado no diretório de saída wwwroot, para que o navegador possa recuperar esse arquivo solicitando /service-worker-assets.js. Para ver o conteúdo desse arquivo, abra /bin/Debug/{TARGET FRAMEWORK}/wwwroot/service-worker-assets.js em um editor de texto. No entanto, não edite o arquivo, pois ele é regenerado em cada build.

O manifesto lista:

  • Todos os recursos gerenciados pelo Blazor, como assemblies .NET e arquivos de runtime do .NET WebAssembly necessários para funcionar offline.
  • Todos os recursos para publicação no diretório wwwroot do aplicativo, como imagens, folhas de estilos e arquivos JavaScript, incluindo ativos da Web estáticos fornecidos por projetos externos e pacotes NuGet.

Você pode controlar quais desses recursos são buscados e armazenados em cache pelo trabalhador do serviço editando a lógica de onInstall em service-worker.published.js. O trabalho de serviço busca e armazena em cache arquivos que correspondem a extensões típicas de nome de arquivo da Web, como .html, .css, .js e .wasm, além de tipos de arquivo específicos para Blazor WebAssembly, como arquivos .pdb (todas as versões) e arquivos .dll (ASP .NET Core no .NET 7 ou anterior).

Para incluir recursos adicionais que não estão presentes no diretório do aplicativo, defina entradas extras do wwwroot MSBuild ItemGroup, conforme mostrado no exemplo a seguir:

<ItemGroup>
  <ServiceWorkerAssetsManifestItem Include="MyDirectory\AnotherFile.json"
    RelativePath="MyDirectory\AnotherFile.json" AssetUrl="files/AnotherFile.json" />
</ItemGroup>

Os metadados AssetUrl especificam a URL relativa à base que o navegador deve usar ao buscar o recurso para armazenar em cache. Isso pode ser independente do nome do arquivo de origem original no disco.

Importante

Adicionar um ServiceWorkerAssetsManifestItem não faz com que o arquivo seja publicado no diretório do aplicativo wwwroot. A saída de publicação deve ser controlada separadamente. O ServiceWorkerAssetsManifestItem único faz com que uma entrada adicional apareça no manifesto de ativos de trabalho do serviço.

Notificações por push

Como qualquer outro PWA, um PWA do Blazor WebAssembly pode receber notificações por push de um servidor de back-end. O servidor pode enviar notificações por push a qualquer momento, mesmo quando o usuário não está usando ativamente o aplicativo. Por exemplo, as notificações por push podem ser enviadas quando um usuário diferente executa uma ação relevante.

O mecanismo para enviar uma notificação por push é totalmente independente do Blazor WebAssembly, uma vez que é implementado pelo servidor de back-end que pode usar qualquer tecnologia. Se você quiser enviar notificações por push de um servidor ASP.NET Core, considere usar uma técnica semelhante à abordagem feita na oficina Blazing Pizza.

O mecanismo para receber e exibir uma notificação por push no cliente também é independente do Blazor WebAssembly, já que ele é implementado no arquivo JavaScript do service worker. Para obter um exemplo, consulte a abordagem usada na oficina Blazing Pizza.

Advertências para PWAs offline

Nem todos os aplicativos devem tentar dar suporte ao uso offline. O suporte offline adiciona complexidade significativa, embora nem sempre seja relevante para os casos de uso necessários.

O suporte offline geralmente é relevante apenas:

  • Se o repositório de dados primário for local para o navegador. Por exemplo, a abordagem é relevante em um aplicativo com uma interface do usuário para um dispositivo IoT que armazena dados em localStorage ou IndexedDB.
  • Se o aplicativo executar uma quantidade significativa de trabalho para buscar e armazenar em cache os dados da API de back-end relevantes para cada usuário para que ele possa navegar pelos dados offline. Se o aplicativo precisar dar suporte à edição, um sistema para acompanhar as alterações e sincronizar dados com o back-end deverá ser criado.
  • Se o objetivo for garantir que o aplicativo seja carregado imediatamente, independentemente das condições de rede. Implemente uma experiência de usuário adequada em torno de solicitações de API de back-end para mostrar o progresso das solicitações e se comportar normalmente quando as solicitações falham devido à indisponibilidade da rede.

Além disso, PWAs com capacidade offline devem lidar com uma série de complicações adicionais. Os desenvolvedores devem se familiarizar cuidadosamente com as advertências nas seções a seguir.

Suporte offline somente quando publicado

Durante o desenvolvimento, você normalmente deseja ver cada alteração refletida imediatamente no navegador sem passar por um processo de atualização em segundo plano. Portanto, o modelo PWA do Blazor habilita o suporte offline somente quando publicado.

Ao criar um aplicativo com capacidade offline, não é suficiente testar o aplicativo no ambiente Development. Você deve testar o aplicativo em seu estado publicado para entender como ele responde a diferentes condições de rede.

Conclusão da atualização após a navegação do usuário longe do aplicativo

Atualizações não concluir até que o usuário tenha navegado para longe do aplicativo em todas as guias. Conforme explicado na seção Atualizações em segundo plano, depois de implantar uma atualização no aplicativo, o navegador busca os arquivos de trabalho de serviço atualizados para iniciar o processo de atualização.

O que surpreende muitos desenvolvedores é que, mesmo quando essa atualização é concluída, ela não entra em vigor até que o usuário tenha navegado para longe em todas as guias. Não é suficiente atualizar a guia exibindo o aplicativo, mesmo que seja a única guia que exibe o aplicativo. Até que seu aplicativo esteja completamente fechado, o novo trabalho de serviço permanecerá na espera para ativar o status. Isso não é específico oara Blazor, mas sim um comportamento padrão da plataforma Web.

Isso geralmente incomoda os desenvolvedores que estão tentando testar atualizações para seu trabalho de serviço ou recursos armazenados em cache offline. Se você marcar nas ferramentas de desenvolvedor do navegador, poderá ver algo semelhante ao seguinte:

A guia

Enquanto a lista de "clientes", que são guias ou janelas que exibem seu aplicativo, não estiver vazia, o trabalhador continuará aguardando. O motivo pelo qual os trabalhadores do serviço fazem isso é para garantir a consistência. Consistência significa que todos os recursos são buscados do mesmo cache atômico.

Ao testar alterações, talvez seja conveniente clicar no link "skipWaiting", conforme mostrado na captura de tela anterior, e recarregar a página. Você pode automatizar isso para todos os usuários codificando seu trabalho de serviço para ignorar a fase de "espera" e ativar imediatamente na atualização. Se você ignorar a fase de espera, estará abrindo mão da garantia de que os recursos são sempre buscados consistentemente da mesma instância de cache.

Os usuários podem executar qualquer versão histórica do aplicativo

Os desenvolvedores da Web normalmente esperam que os usuários executem apenas a versão mais recente implantada de seu aplicativo Web, pois isso é normal dentro do modelo de distribuição da Web tradicional. No entanto, um PWA offline-first é mais semelhante a um aplicativo móvel nativo, em que os usuários não estão necessariamente executando a versão mais recente.

Conforme explicado na seção Atualizações em segundo plano, depois que você implanta uma atualização em seu aplicativo, cada usuário existente continua a usar uma versão anterior para pelo menos mais uma visita porque a atualização ocorre em segundo plano e não é ativada até que o usuário vá embora. Além disso, a versão anterior que está sendo usada não é necessariamente a anterior que você implantou. A versão anterior pode ser qualquer versão histórica, dependendo de quando o usuário concluiu uma atualização pela última vez.

Isso pode ser um problema se as partes de front-end e back-end do aplicativo exigirem um contrato sobre o esquema para solicitações de API. Você não deve implantar alterações de esquema de API incompatíveis com versões anteriores até ter certeza de que todos os usuários atualizaram. Como alternativa, impeça que os usuários usem versões mais antigas incompatíveis do aplicativo. Esse requisito de cenário é o mesmo que para aplicativos móveis nativos. Se você implantar uma alteração interruptiva nas APIs do servidor, o aplicativo cliente será interrompido para usuários que ainda não atualizaram.

Se possível, não implante alterações interruptivas em suas APIs de back-end. Se você precisar fazer isso, considere usar APIs padrão do Service Worker, como ServiceWorkerRegistration, para determinar se o aplicativo está atualizado e, caso contrário, para impedir o uso.

Interferência com páginas renderizadas pelo servidor

Conforme descrito na seção Páginas renderizadas pelo servidor de suporte, se você quiser ignorar o comportamento do service worker de retornar conteúdos /index.html para todas as solicitações de navegação, edite a lógica em seu service worker.

Todo o conteúdo do manifesto do ativos do serviço de trabalho é armazenado em cache por padrão

Conforme descrito na seçãoCache de ativos de controle, o arquivo service-worker-assets.js é gerado durante o build e lista todos os ativos que o service worker deve buscar e armazenar em cache.

Como essa lista por padrão inclui tudo o que é emitido para wwwroot, incluindo o conteúdo fornecido por pacotes e projetos externos, você deve ter cuidado para não colocar muito conteúdo lá. Se o diretório wwwroot contiver milhões de imagens, o service worker tentará buscar e armazenar em cache todas elas, consumindo largura de banda excessiva e provavelmente não concluindo com êxito.

Implemente a lógica arbitrária para controlar qual subconjunto do conteúdo do manifesto deve ser buscado e armazenado em cache editando a onInstall função em service-worker.published.js.

Interação com autenticação

O modelo do PWA pode ser usado em conjunto com a autenticação. Um PWA com capacidade offline também pode dar suporte à autenticação quando o usuário tem conectividade de rede inicial.

Quando um usuário não tem conectividade de rede, ele não pode autenticar ou obter tokens de acesso. Tentar visitar a página de logon sem acesso à rede resulta em uma mensagem de "erro de rede". Você deve criar um fluxo de interface do usuário que permita que o usuário execute tarefas úteis enquanto estiver offline sem tentar autenticar o usuário ou obter tokens de acesso. Como alternativa, você pode projetar o aplicativo para falhar normalmente quando a rede não estiver disponível. Se o aplicativo não puder ser projetado para lidar com esses cenários, talvez você não queira habilitar o suporte offline.

Quando um aplicativo projetado para uso online e offline estiver online novamente:

  • O aplicativo pode precisar provisionar um novo token de acesso.
  • O aplicativo deve detectar se um usuário diferente está conectado ao serviço para que ele possa aplicar operações à conta do usuário que foram feitas enquanto eles estavam offline.

Para criar um aplicativo PWA offline que interage com a autenticação:

  • Substitua o AccountClaimsPrincipalFactory<TAccount> por uma fábrica que armazena o último usuário conectado e usa o usuário armazenado quando o aplicativo está offline.
  • Enfileire operações enquanto o aplicativo está offline e as aplique quando o aplicativo retornar a ficar online.
  • Durante a saída, limpe o usuário armazenado.

O aplicativo de exemplo CarChecker demonstra as abordagens anteriores. Confira as seguintes partes do aplicativo:

  • OfflineAccountClaimsPrincipalFactory (Client/Data/OfflineAccountClaimsPrincipalFactory.cs)
  • LocalVehiclesStore (Client/Data/LocalVehiclesStore.cs)
  • Componente LoginStatus (Client/Shared/LoginStatus.razor)

Recursos adicionais