ASP.NET Core Blazor Progressive Web Application (PWA)

Nota

Questa non è la versione più recente di questo articolo. Per la versione corrente, vedere la versione .NET 8 di questo articolo.

Importante

Queste informazioni si riferiscono a un prodotto non definitive che può essere modificato in modo sostanziale prima che venga rilasciato commercialmente. Microsoft non riconosce alcuna garanzia, espressa o implicita, in merito alle informazioni qui fornite.

Per la versione corrente, vedere la versione .NET 8 di questo articolo.

Un'applicazione Blazor Web progressiva (PWA) è un'applicazione a pagina singola che usa API e funzionalità moderne del browser per comportarsi come un'app desktop.

Blazor WebAssembly è una piattaforma di app Web sul lato client basata su standard, in modo che possa usare qualsiasi API del browser, incluse le API PWA necessarie per le funzionalità seguenti:

  • Lavorare offline e caricare immediatamente, indipendentemente dalla velocità di rete.
  • In esecuzione nella propria finestra dell'app, non solo in una finestra del browser.
  • Avviato dal menu Start del sistema operativo dell'host, dal dock o dalla schermata iniziale.
  • Ricezione di notifiche push da un server back-end, anche se l'utente non usa l'app.
  • Aggiornamento automatico in background.

La parola progressive viene usata per descrivere queste app perché:

  • Un utente potrebbe prima individuare e usare l'app all'interno del Web browser come qualsiasi altra applicazione a pagina singola.
  • Successivamente, l'utente procede all'installazione nel sistema operativo e abilita le notifiche push.

Creare un progetto dal modello PWA

Quando si crea una nuova Blazor WebAssembly app, selezionare la casella di controllo Applicazione Web progressiva.

Facoltativamente, è possibile configurare PWA per un'app creata dal modello di progetto core ospitatoBlazor WebAssembly ASP.NET. Lo scenario PWA è indipendente dal modello di hosting.

Convertire un'app esistente Blazor WebAssembly in una pwa

Convertire un'app esistente Blazor WebAssembly in pwa seguendo le indicazioni riportate in questa sezione.

Nel file di progetto dell'app:

  • Aggiungere la proprietà seguente ServiceWorkerAssetsManifest a un oggetto PropertyGroup:

      ...
      <ServiceWorkerAssetsManifest>service-worker-assets.js</ServiceWorkerAssetsManifest>
    </PropertyGroup>
    
  • Aggiungere l'elemento seguente ServiceWorker a un oggetto ItemGroup:

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

Per ottenere asset statici, usare uno degli approcci seguenti:

  • Creare un nuovo progetto PWA separato con il dotnet new comando in una shell dei comandi:

    dotnet new blazorwasm -o MyBlazorPwa --pwa
    

    Nel comando precedente l'opzione -o|--output crea una nuova cartella per l'app denominata MyBlazorPwa.

    Se non si converte un'app per la versione più recente, passare l'opzione -f|--framework . L'esempio seguente crea l'app per ASP.NET Core versione 5.0:

    dotnet new blazorwasm -o MyBlazorPwa --pwa -f net5.0
    
  • Passare al repository GitHub di ASP.NET Core all'URL seguente, che collega all'origine e agli asset di riferimento del main ramo. Selezionare la versione che si sta usando dall'elenco a discesa Switch branch or tags (Cambia rami o tag ) applicabile all'app.

    Blazor WebAssembly Cartella del modello wwwroot di progetto (dotnet/aspnetcore ramo del repository main GitHub)

    Nota

    I collegamenti della documentazione all'origine del riferimento .NET in genere caricano il ramo predefinito del repository, che rappresenta lo sviluppo corrente per la versione successiva di .NET. Per selezionare un tag per una versione specifica, usare l'elenco a discesa Switch branches or tags. Per altre informazioni, vedere How to select a version tag of ASP.NET Core source code (dotnet/AspNetCore.Docs #26205) (Come selezionare un tag di versione del codice sorgente di ASP.NET - dotnet/AspNetCore.Docs #26205).

    Dalla cartella di origine wwwroot nell'app creata o dagli asset di riferimento nel dotnet/aspnetcore repository GitHub copiare i file seguenti nella cartella dell'app wwwroot :

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

Nel file dell'app wwwroot/index.html :

  • Aggiungere <link> elementi per il manifesto e l'icona dell'app:

    <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" />
    
  • Passare al repository GitHub di ASP.NET Core all'URL seguente, che collega all'origine e agli asset di riferimento del release/7.0 ramo. Se si usa una versione di ASP.NET Core successiva alla 7.0, modificare il selettore della versione del documento per visualizzare le indicazioni aggiornate per questa sezione. Selezionare la versione che si sta usando dall'elenco a discesa Switch branch or tags (Cambia rami o tag ) applicabile all'app.

    Blazor WebAssembly Cartella del modello wwwroot di progetto (dotnet/aspnetcore ramo del repository release/7.0 GitHub)

    Nota

    I collegamenti della documentazione all'origine del riferimento .NET in genere caricano il ramo predefinito del repository, che rappresenta lo sviluppo corrente per la versione successiva di .NET. Per selezionare un tag per una versione specifica, usare l'elenco a discesa Switch branches or tags. Per altre informazioni, vedere How to select a version tag of ASP.NET Core source code (dotnet/AspNetCore.Docs #26205) (Come selezionare un tag di versione del codice sorgente di ASP.NET - dotnet/AspNetCore.Docs #26205).

    Dalla cartella di origine wwwroot nell'app creata o dagli asset di riferimento nel dotnet/aspnetcore repository GitHub copiare i file seguenti nella cartella dell'app wwwroot :

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

Nel file dell'app wwwroot/index.html :

  • Aggiungere <link> elementi per il manifesto e l'icona dell'app:

    <link href="manifest.json" rel="manifest" />
    <link rel="apple-touch-icon" sizes="512x512" href="icon-512.png" />
    
  • Aggiungere il tag seguente <script> all'interno del tag di chiusura </body> immediatamente dopo il blazor.webassembly.js tag script:

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

Installazione e manifesto dell'app

Quando si visita un'app creata usando il modello PWA, gli utenti hanno la possibilità di installare l'app nel menu Start, nel dock o nella schermata iniziale del sistema operativo. La modalità di presentazione di questa opzione dipende dal browser dell'utente. Quando si usano browser basati su Chromium desktop, ad esempio Edge o Chrome, viene visualizzato un pulsante Aggiungi nella barra degli URL. Dopo aver selezionato il pulsante Aggiungi , l'utente riceve una finestra di dialogo di conferma:

La finestra di dialogo di conferma in Google Chrome presenta un pulsante Installa all'utente per l'app

In iOS i visitatori possono installare PWA usando il pulsante Condividi di Safari e la relativa opzione Aggiungi alla Homeschermata. In Chrome per Android gli utenti devono selezionare il pulsante Menu nell'angolo in alto a destra, seguito da Aggiungi alla Home schermata.

Dopo l'installazione, l'app viene visualizzata nella propria finestra senza una barra degli indirizzi:

L'app

Per personalizzare il titolo, la combinazione di colori, l'icona o altri dettagli della finestra, vedere il manifest.json file nella directory del wwwroot progetto. Lo schema di questo file è definito dagli standard Web. Per altre informazioni, vedere La documentazione Web MDN: Manifesto dell'app Web.

Supporto offline

Per impostazione predefinita, le app create con l'opzione modello PWA supportano l'esecuzione offline. Un utente deve prima visitare l'app mentre è online. Il browser scarica e memorizza nella cache automaticamente tutte le risorse necessarie per funzionare offline.

Importante

Il supporto dello sviluppo interferisce con il normale ciclo di sviluppo di apportare modifiche e testarle. Pertanto, il supporto offline è abilitato solo per le app pubblicate .

Avviso

Se si intende distribuire un PWA abilitato per la modalità offline, sono presenti diversi avvisi e avvertenze importanti. Questi scenari sono intrinseci di PWA offline e non specifici di Blazor. Assicurarsi di leggere e comprendere queste avvertenze prima di fare ipotesi sul funzionamento dell'app abilitata per la modalità offline.

Per informazioni sul funzionamento del supporto offline:

  1. Pubblica l'app. Per altre informazioni, vedere Ospitare e distribuire ASP.NET Core Blazor.

  2. Distribuire l'app in un server che supporta HTTPS e accedere all'app in un browser all'indirizzo HTTPS sicuro.

  3. Aprire gli strumenti di sviluppo del browser e verificare che un ruolo di lavoro del servizio sia registrato per l'host nella scheda Applicazione :

    La scheda

  4. Ricaricare la pagina ed esaminare la scheda Rete . Il ruolo di lavoro del servizio o la cache della memoria sono elencati come origini per tutti gli asset della pagina:

    Scheda

  5. Per verificare che il browser non sia dipendente dall'accesso alla rete per caricare l'app, eseguire le operazioni seguenti:

    • Arrestare il server Web e vedere come l'app continua a funzionare normalmente, che include ricaricamenti di pagina. Analogamente, l'app continua a funzionare normalmente quando è presente una connessione di rete lenta.
    • Indicare al browser di simulare la modalità offline nella scheda Rete :

    La scheda

Il supporto offline con un ruolo di lavoro del servizio è uno standard Web, non specifico di Blazor. Per altre informazioni sui ruoli di lavoro del servizio, vedere La documentazione Web mdn: API del ruolo di lavoro del servizio. Per altre informazioni sui modelli di utilizzo comuni per i ruoli di lavoro dei servizi, vedere Google Web: The Service Worker Lifecycle(Ciclo di vita del ruolo di lavoro del servizio).

BlazorIl modello di PWA produce due file di lavoro del servizio:

  • wwwroot/service-worker.js, che viene usato durante lo sviluppo.
  • wwwroot/service-worker.published.js, che viene usato dopo la pubblicazione dell'app.

Per condividere la logica tra i due file di lavoro del servizio, considerare l'approccio seguente:

  • Aggiungere un terzo file JavaScript per contenere la logica comune.
  • Usare self.importScripts per caricare la logica comune in entrambi i file di lavoro del servizio.

Strategia di recupero cache-first

Il ruolo di lavoro del service-worker.published.js servizio predefinito risolve le richieste usando una strategia cache-first . Ciò significa che il ruolo di lavoro del servizio preferisce restituire contenuto memorizzato nella cache, indipendentemente dal fatto che l'utente disponga dell'accesso alla rete o del contenuto più recente sia disponibile nel server.

La strategia cache-first è utile perché:

  • Garantisce l'affidabilità. L'accesso alla rete non è uno stato booleano. Un utente non è semplicemente online o offline:

    • Il dispositivo dell'utente può presupporre che sia online, ma la rete potrebbe essere così lenta da essere poco pratica da attendere.
    • La rete potrebbe restituire risultati non validi per determinati URL, ad esempio quando è presente un portale WIFI captive che attualmente blocca o reindirizza determinate richieste.

    Ecco perché l'API del navigator.onLine browser non è affidabile e non deve dipendere.

  • Garantisce la correttezza. Quando si compila una cache di risorse offline, il ruolo di lavoro del servizio usa l'hashing del contenuto per garantire che abbia recuperato uno snapshot completo e auto-coerente delle risorse in un singolo istante. Questa cache viene quindi usata come unità atomica. Non è necessario chiedere alla rete le risorse più recenti, perché le uniche versioni necessarie sono quelle già memorizzate nella cache. Qualsiasi altro rischio di incoerenza e incompatibilità ( ad esempio, tentativo di usare versioni di assembly .NET non compilati insieme).

Se è necessario impedire al browser di recuperare service-worker-assets.js dalla cache HTTP, ad esempio per risolvere gli errori di controllo dell'integrità temporanei durante la distribuzione di una nuova versione del ruolo di lavoro del servizio, aggiornare la registrazione del ruolo di lavoro del servizio in wwwroot/index.html con updateViaCache impostato su 'none':

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

Aggiornamenti in background

Come modello mentale, puoi pensare a un PWA offline come un'app per dispositivi mobili che può essere installata. L'app viene avviata immediatamente indipendentemente dalla connettività di rete, ma la logica dell'app installata proviene da uno snapshot temporizzato che potrebbe non essere la versione più recente.

Il Blazor modello PWA produce app che tentano automaticamente di aggiornarsi in background ogni volta che l'utente visita e ha una connessione di rete funzionante. Il modo in cui funziona è il seguente:

  • Durante la compilazione, il progetto genera un manifesto degli asset del ruolo di lavoro del servizio. Per impostazione predefinita, viene chiamato service-worker-assets.js. Il manifesto elenca tutte le risorse statiche richieste dall'app per funzionare offline, ad esempio assembly .NET, file JavaScript e CSS, inclusi gli hash del contenuto. L'elenco di risorse viene caricato dal ruolo di lavoro del servizio in modo che conosca le risorse da memorizzare nella cache.
  • Ogni volta che l'utente visita l'app, il browser richiede nuovamente service-worker.js e service-worker-assets.js in background. I file vengono confrontati in byte per byte con il ruolo di lavoro del servizio installato esistente. Se il server restituisce contenuto modificato per uno di questi file, il ruolo di lavoro del servizio tenta di installare una nuova versione di se stessa.
  • Quando si installa una nuova versione di se stessa, il ruolo di lavoro del servizio crea una nuova cache separata per le risorse offline e inizia a popolare la cache con le risorse elencate in service-worker-assets.js. Questa logica viene implementata nella onInstall funzione all'interno service-worker.published.jsdi .
  • Il processo viene completato correttamente quando tutte le risorse vengono caricate senza errori e tutti gli hash di contenuto corrispondono. In caso di esito positivo, il nuovo ruolo di lavoro del servizio entra in attesa dello stato di attivazione . Non appena l'utente chiude l'app (nessuna scheda o finestra rimanente dell'app), il nuovo ruolo di lavoro del servizio diventa attivo e viene usato per le visite successive all'app. Il ruolo di lavoro del servizio precedente e la relativa cache vengono eliminati.
  • Se il processo non viene completato correttamente, la nuova istanza del ruolo di lavoro del servizio viene rimossa. Il processo di aggiornamento viene provato di nuovo nella visita successiva dell'utente, quando si spera che il client disponga di una connessione di rete migliore in grado di completare le richieste.

Personalizzare questo processo modificando la logica del ruolo di lavoro del servizio. Nessuno dei comportamenti precedenti è specifico, Blazor ma è semplicemente l'esperienza predefinita fornita dall'opzione modello PWA. Per altre informazioni, vedere La documentazione Web mdn: API del ruolo di lavoro del servizio.

Come vengono risolte le richieste

Come descritto nella sezione Strategia di recupero cache-first, il ruolo di lavoro del servizio predefinito usa una strategia cache-first , ovvero tenta di gestire il contenuto memorizzato nella cache quando disponibile. Se non è presente contenuto memorizzato nella cache per un determinato URL, ad esempio quando si richiedono dati da un'API back-end, il ruolo di lavoro del servizio esegue il fallback su una normale richiesta di rete. La richiesta di rete ha esito positivo se il server è raggiungibile. Questa logica viene implementata all'interno della funzione all'interno onFetch di service-worker.published.js.

Se i componenti dell'app si basano sulla richiesta di dati dalle API back-end e si vuole offrire un'esperienza utente semplice per le richieste non riuscite a causa dell'indisponibilità della Razor rete, implementare la logica all'interno dei componenti dell'app. Ad esempio, usare try/catch le richieste.HttpClient

Supportare le pagine di cui è stato eseguito il rendering nel server

Considerare cosa accade quando l'utente passa per la prima volta a un URL, /counter ad esempio o a qualsiasi altro collegamento diretto nell'app. In questi casi, non si vuole restituire il contenuto memorizzato nella cache come /counter, ma è necessario che il browser carichi il contenuto memorizzato nella cache per /index.html avviare Blazor WebAssembly l'app. Queste richieste iniziali sono note come richieste di spostamento , anziché:

  • subresource richieste di immagini, fogli di stile o altri file.
  • fetch/XHR richieste di dati API.

Il ruolo di lavoro del servizio predefinito contiene la logica del caso speciale per le richieste di spostamento. Il ruolo di lavoro del servizio risolve le richieste restituendo il contenuto memorizzato nella cache per /index.html, indipendentemente dall'URL richiesto. Questa logica viene implementata nella onFetch funzione all'interno service-worker.published.jsdi .

Se l'app dispone di determinati URL che devono restituire codice HTML di cui è stato eseguito il rendering del server e che non servono /index.html dalla cache, è necessario modificare la logica nel ruolo di lavoro del servizio. Se tutti gli URL contenenti /Identity/ devono essere gestiti come normali richieste solo online al server, modificare la service-worker.published.jsonFetch logica. Individuare il seguente codice:

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

Modificare il codice come illustrato di seguito:

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

Se non si esegue questa operazione, indipendentemente dalla connettività di rete, il ruolo di lavoro del servizio intercetta le richieste per tali URL e le risolve usando /index.html.

Aggiungere altri endpoint per i provider di autenticazione esterni al controllo. Nell'esempio seguente, /signin-google per l'autenticazione di Google viene aggiunto al controllo:

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

Non è necessaria alcuna azione per l'ambiente Development , in cui il contenuto viene sempre recuperato dalla rete.

Controllare la memorizzazione nella cache degli asset

Se il progetto definisce la ServiceWorkerAssetsManifest proprietà MSBuild, Blazorgli strumenti di compilazione generano un manifesto degli asset del ruolo di lavoro del servizio con il nome specificato. Il modello PWA predefinito produce un file di progetto contenente la proprietà seguente:

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

Il file viene inserito nella wwwroot directory di output, in modo che il browser possa recuperare il file richiedendo /service-worker-assets.js. Per visualizzare il contenuto di questo file, aprire /bin/Debug/{TARGET FRAMEWORK}/wwwroot/service-worker-assets.js in un editor di testo. Tuttavia, non modificare il file, perché viene rigenerato in ogni compilazione.

Per impostazione predefinita, questo manifesto elenca:

  • Qualsiasi Blazorrisorsa gestita, ad esempio assembly .NET e file di runtime .NET WebAssembly necessari per funzionare offline.
  • Tutte le risorse per la pubblicazione nella directory dell'app wwwroot , ad esempio immagini, fogli di stile e file JavaScript, inclusi gli asset Web statici forniti da progetti esterni e pacchetti NuGet.

È possibile controllare quali di queste risorse vengono recuperate e memorizzate nella cache dal ruolo di lavoro del servizio modificando la logica in onInstall in service-worker.published.js. Per impostazione predefinita, il ruolo di lavoro del servizio recupera e memorizza nella cache i file corrispondenti alle tipiche estensioni di file Web, ad .htmlesempio , .css.js, e .wasm, oltre ai tipi di file specifici di Blazor WebAssembly, ad esempio .pdb i file (tutte le versioni) e .dll i file (ASP.NET Core in .NET 7 o versioni precedenti).

Per includere risorse aggiuntive che non sono presenti nella directory dell'app wwwroot , definire voci MSBuild ItemGroup aggiuntive, come illustrato nell'esempio seguente:

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

I AssetUrl metadati specificano l'URL relativo alla base che il browser deve usare durante il recupero della risorsa nella cache. Può essere indipendente dal nome del file di origine originale sul disco.

Importante

L'aggiunta di un ServiceWorkerAssetsManifestItem oggetto non causa la pubblicazione del file nella directory dell'app wwwroot . L'output di pubblicazione deve essere controllato separatamente. L'unica ServiceWorkerAssetsManifestItem causa la visualizzazione di una voce aggiuntiva nel manifesto degli asset del ruolo di lavoro del servizio.

Notifiche push

Come qualsiasi altro PWA, un Blazor WebAssembly pwa può ricevere notifiche push da un server back-end. Il server può inviare notifiche push in qualsiasi momento, anche quando l'utente non usa attivamente l'app. Ad esempio, le notifiche push possono essere inviate quando un utente diverso esegue un'azione pertinente.

Il meccanismo per l'invio di Blazor WebAssemblyuna notifica push è completamente indipendente da , poiché viene implementato dal server back-end che può usare qualsiasi tecnologia. Se si vogliono inviare notifiche push da un server ASP.NET Core, è consigliabile usare una tecnica simile all'approccio adottato nel workshop Blazing Pizza.

Il meccanismo per la ricezione e la visualizzazione di una notifica push nel client è anche indipendente da Blazor WebAssembly, poiché viene implementato nel file JavaScript del ruolo di lavoro del servizio. Per un esempio, vedere l'approccio usato nel workshop Blazing Pizza.

Avvertenze per pwa offline

Non tutte le app devono tentare di supportare l'uso offline. Il supporto offline aggiunge una complessità significativa, pur non essendo sempre rilevante per i casi d'uso necessari.

Il supporto offline è in genere rilevante solo:

  • Se l'archivio dati primario è locale nel browser. Ad esempio, l'approccio è rilevante in un'app con un'interfaccia utente per un dispositivo IoT che archivia i dati in localStorage o IndexedDB.
  • Se l'app esegue una notevole quantità di lavoro per recuperare e memorizzare nella cache i dati dell'API back-end rilevanti per ogni utente in modo che possano spostarsi tra i dati offline. Se l'app deve supportare la modifica, è necessario compilare un sistema per tenere traccia delle modifiche e sincronizzare i dati con il back-end.
  • Se l'obiettivo è garantire che l'app venga caricata immediatamente indipendentemente dalle condizioni di rete. Implementare un'esperienza utente appropriata per le richieste API back-end per mostrare lo stato di avanzamento delle richieste e comportarsi normalmente quando le richieste hanno esito negativo a causa dell'indisponibilità della rete.

Inoltre, le PWA con supporto offline devono gestire una serie di complicazioni aggiuntive. Gli sviluppatori devono acquisire attentamente familiarità con le avvertenze riportate nelle sezioni seguenti.

Supporto offline solo quando pubblicato

Durante lo sviluppo si vuole in genere visualizzare ogni modifica riflessa immediatamente nel browser senza passare attraverso un processo di aggiornamento in background. Di conseguenza, Blazoril modello PWA abilita il supporto offline solo quando viene pubblicato.

Quando si compila un'app con supporto offline, non è sufficiente testare l'app nell'ambiente Development . È necessario testare l'app nello stato pubblicato per comprendere in che modo risponde a diverse condizioni di rete.

Completamento dell'aggiornamento dopo lo spostamento dell'utente dall'app

Aggiornamenti non completare finché l'utente non si è spostato dall'app in tutte le schede. Come spiegato nella sezione Aggiornamenti in background, dopo aver distribuito un aggiornamento all'app, il browser recupera i file di lavoro del servizio aggiornati per avviare il processo di aggiornamento.

Ciò che sorprende molti sviluppatori è che, anche quando questo aggiornamento viene completato, non diventa effettivo fino a quando l'utente non si è spostato in tutte le schede. Non è sufficiente aggiornare la scheda che visualizza l'app, anche se è l'unica scheda che visualizza l'app. Fino a quando l'app non viene completamente chiusa, il nuovo ruolo di lavoro del servizio rimane in attesa di attivare lo stato. Questo non è specifico di Blazor, ma piuttosto è un comportamento standard della piattaforma Web.

Questo problema si verifica in genere per gli sviluppatori che tentano di testare gli aggiornamenti al proprio ruolo di lavoro del servizio o alle risorse memorizzate nella cache offline. Se si selezionano gli strumenti di sviluppo del browser, è possibile che venga visualizzato un aspetto simile al seguente:

La scheda

Se l'elenco di "client", ovvero schede o finestre che visualizzano l'app, non è un problema, il ruolo di lavoro continua ad attendere. Il motivo per cui i lavoratori del servizio fanno questo è garantire la coerenza. Coerenza significa che tutte le risorse vengono recuperate dalla stessa cache atomica.

Quando si testano le modifiche, potrebbe risultare utile selezionare il collegamento "skipWaiting", come illustrato nello screenshot precedente, quindi ricaricare la pagina. È possibile automatizzare questa operazione per tutti gli utenti codificando il ruolo di lavoro del servizio per ignorare la fase di attesa e attivarla immediatamente all'aggiornamento. Se si ignora la fase di attesa, si rinuncia alla garanzia che le risorse vengano sempre recuperate in modo coerente dalla stessa istanza della cache.

Gli utenti possono eseguire qualsiasi versione cronologica dell'app

Gli sviluppatori Web si aspettano abitualmente che gli utenti eseguano solo la versione distribuita più recente dell'app Web, perché è normale all'interno del modello di distribuzione Web tradizionale. Tuttavia, un PWA offline è più simile a un'app per dispositivi mobili nativa, in cui gli utenti non eseguono necessariamente la versione più recente.

Come spiegato nella sezione Aggiornamenti in background, dopo aver distribuito un aggiornamento all'app, ogni utente esistente continua a usare una versione precedente per almeno un'altra visita perché l'aggiornamento si verifica in background e non viene attivato fino a quando l'utente non si allontana. Inoltre, la versione precedente usata non è necessariamente quella precedente distribuita. La versione precedente può essere qualsiasi versione cronologica, a seconda dell'ultimo completamento di un aggiornamento da parte dell'utente.

Questo può essere un problema se le parti front-end e back-end dell'app richiedono un accordo sullo schema per le richieste API. Non è necessario distribuire le modifiche dello schema API non compatibili con le versioni precedenti fino a quando non è possibile assicurarsi che tutti gli utenti siano stati aggiornati. In alternativa, impedire agli utenti di usare versioni precedenti incompatibili dell'app. Questo requisito di scenario è identico a quello per le app per dispositivi mobili native. Se si distribuisce una modifica che causa un'interruzione nelle API del server, l'app client viene interrotta per gli utenti che non sono ancora stati aggiornati.

Se possibile, non distribuire modifiche di rilievo alle API back-end. In tal caso, è consigliabile usare API di lavoro di servizio standard, ad esempio ServiceWorkerRegistration , per determinare se l'app è aggiornata e, in caso contrario, per impedire l'utilizzo.

Interferenza con le pagine di cui è stato eseguito il rendering del server

Come descritto nella sezione Supporto delle pagine sottoposte a rendering del server, se si vuole ignorare il comportamento del ruolo di lavoro del servizio di restituzione /index.html del contenuto per tutte le richieste di spostamento, modificare la logica nel ruolo di lavoro del servizio.

Tutti i contenuti del manifesto dell'asset del ruolo di lavoro del servizio vengono memorizzati nella cache per impostazione predefinita

Come descritto nella sezione Memorizzazione nella cache degli asset di controllo, il file service-worker-assets.js viene generato durante la compilazione ed elenca tutti gli asset che il ruolo di lavoro del servizio deve recuperare e memorizzare nella cache.

Poiché questo elenco include per impostazione predefinita tutti gli elementi generati in wwwroot, incluso il contenuto fornito da pacchetti e progetti esterni, è necessario prestare attenzione a non inserire troppo contenuto. Se la wwwroot directory contiene milioni di immagini, il ruolo di lavoro del servizio tenta di recuperarli e memorizzarli tutti nella cache, consumando una larghezza di banda eccessiva e probabilmente non completando correttamente.

Implementare logica arbitraria per controllare quale subset del contenuto del manifesto deve essere recuperato e memorizzato nella cache modificando la onInstall funzione in service-worker.published.js.

Interazione con l'autenticazione

Il modello PWA può essere usato insieme all'autenticazione. Una pwa con supporto offline può supportare anche l'autenticazione quando l'utente dispone della connettività di rete iniziale.

Quando un utente non ha connettività di rete, non può autenticarsi o ottenere token di accesso. Per impostazione predefinita, il tentativo di visitare la pagina di accesso senza accesso alla rete genera un messaggio di errore di rete. È necessario progettare un flusso dell'interfaccia utente che consenta all'utente di eseguire attività utili offline senza tentare di autenticare l'utente o ottenere i token di accesso. In alternativa, è possibile progettare l'app in modo che non riesca correttamente quando la rete non è disponibile. Se l'app non può essere progettata per gestire questi scenari, potrebbe non essere necessario abilitare il supporto offline.

Quando un'app progettata per l'uso online e offline è di nuovo online:

  • L'app potrebbe dover effettuare il provisioning di un nuovo token di accesso.
  • L'app deve rilevare se un utente diverso ha eseguito l'accesso al servizio in modo che possa applicare operazioni all'account dell'utente eseguito mentre erano offline.

Per creare un'app PWA offline che interagisce con l'autenticazione:

  • AccountClaimsPrincipalFactory<TAccount> Sostituire con una factory che archivia l'ultimo utente connesso e usa l'utente archiviato quando l'app è offline.
  • Operazioni di accodamento mentre l'app è offline e applicarle quando l'app torna online.
  • Durante la disconnessa, cancellare l'utente archiviato.

L'app CarChecker di esempio illustra gli approcci precedenti. Vedere le parti seguenti dell'app:

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

Risorse aggiuntive