Delen via


ASP.NET Core Blazor Progressive Web Application (PWA)

Notitie

Dit is niet de nieuwste versie van dit artikel. Zie de .NET 9-versie van dit artikelvoor de huidige release.

Waarschuwing

Deze versie van ASP.NET Core wordt niet meer ondersteund. Zie de .NET- en .NET Core-ondersteuningsbeleidvoor meer informatie. Zie de .NET 9-versie van dit artikelvoor de huidige release.

Belangrijk

Deze informatie heeft betrekking op een pre-releaseproduct dat aanzienlijk kan worden gewijzigd voordat het commercieel wordt uitgebracht. Microsoft geeft geen garanties, uitdrukkelijk of impliciet, met betrekking tot de informatie die hier wordt verstrekt.

Zie de .NET 9-versie van dit artikelvoor de huidige release.

Een Blazor Progressive Web Application (PWA) is een toepassing met één pagina (SPA) die gebruikmaakt van moderne browser-API's en mogelijkheden om zich te gedragen als een desktop-app.

Blazor WebAssembly is een op standaarden gebaseerd web-app-platform aan de clientzijde, zodat deze elke browser-API kan gebruiken, inclusief PWA-API's die vereist zijn voor de volgende mogelijkheden:

  • Offline werken en direct laden, onafhankelijk van de netwerksnelheid.
  • Wordt uitgevoerd in een eigen app-venster, niet alleen in een browservenster.
  • Wordt gestart vanuit het startmenu van het besturingssysteem van de host, dock of startscherm.
  • Pushmeldingen ontvangen van een back-endserver, zelfs als de gebruiker de app niet gebruikt.
  • Automatisch op de achtergrond bijwerken.

Het woord progressief wordt gebruikt om deze apps te beschrijven, omdat:

  • Een gebruiker kan de app eerst ontdekken en gebruiken in zijn webbrowser, net als elke andere SPA.
  • Later gaat de gebruiker verder met het installeren ervan in het besturingssysteem en het inschakelen van pushmeldingen.

Een project maken op basis van de PWA-sjabloon

Wanneer u een nieuwe Blazor WebAssembly app maakt, schakelt u het selectievakje Progressive Web Application in.

PWA kan eventueel worden geconfigureerd voor een app die is gemaakt op basis van de ASP.NET Core Hosted-projectsjabloonBlazor WebAssembly . Het PWA-scenario is onafhankelijk van het hostingmodel.

Een bestaande Blazor WebAssembly app converteren naar een PWA

Converteer een bestaande Blazor WebAssembly app naar een PWA volgens de richtlijnen in deze sectie.

In het projectbestand van de app:

  • Voeg de volgende ServiceWorkerAssetsManifest eigenschap toe aan een PropertyGroup:

      ...
      <ServiceWorkerAssetsManifest>service-worker-assets.js</ServiceWorkerAssetsManifest>
    </PropertyGroup>
    
  • Voeg het volgende ServiceWorker item toe aan een ItemGroup:

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

Gebruik een van de volgende methoden om statische assets te verkrijgen:

  • Maak een afzonderlijk, nieuw PWA-project met de dotnet new opdracht in een opdrachtshell:

    dotnet new blazorwasm -o MyBlazorPwa --pwa
    

    In de voorgaande opdracht maakt de -o|--output optie een nieuwe map voor de app met de naam MyBlazorPwa.

    Als u geen app converteert voor de nieuwste versie, geeft u de -f|--framework optie door. In het volgende voorbeeld wordt de app gemaakt voor ASP.NET Core versie 5.0:

    dotnet new blazorwasm -o MyBlazorPwa --pwa -f net5.0
    
  • Navigeer naar de ASP.NET Core GitHub-opslagplaats op de volgende URL, welke gekoppeld is aan de bronvermelding van de branch en assets. Selecteer de release waarmee u werkt in de vervolgkeuzelijst Switch-vertakkingen of tags die van toepassing zijn op uw app.

    Blazor WebAssembly projectsjabloon wwwroot (dotnet/aspnetcore tak van de GitHub-opslagplaats main)

    Notitie

    Documentatiekoppelingen naar .NET-referentiebron laden meestal de standaardbranch van de opslagplaats, die de huidige ontwikkeling vertegenwoordigt voor de volgende release van .NET. Als u een tag voor een specifieke release wilt selecteren, gebruikt u de Switch branches of tags vervolgkeuzelijst. Zie Een versietag selecteren van ASP.NET Core-broncode (dotnet/AspNetCore.Docs #26205)voor meer informatie.

    Kopieer vanuit de bronmap wwwroot in de app die u hebt gemaakt of op basis van de referentieassets in de dotnet/aspnetcore GitHub-opslagplaats de volgende bestanden naar de map van wwwroot de app:

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

In het wwwroot/index.html-bestand van de app:

  • Voeg elementen toe <link> voor het manifest- en app-pictogram:

    <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" />
    
  • Navigeer naar de ASP.NET Core GitHub-opslagplaats op de volgende URL, die is gekoppeld aan de referentiebron en assets van de v7.0.0 tag. Als u een versie van ASP.NET Core gebruikt die hoger is dan 7.0, wijzigt u de documentversiekiezer bovenaan dit artikel om de bijgewerkte richtlijnen voor deze sectie te bekijken. Selecteer de release waarmee u werkt in het dropdown-menu Schakel over tussen vertakkingen of tags dat van toepassing is op uw app.

    Blazor WebAssembly project-sjabloonmap wwwroot (v7.0.0 tag)

    Notitie

    Documentatiekoppelingen naar .NET-referentiebron laden meestal de standaardbranch van de opslagplaats, die de huidige ontwikkeling vertegenwoordigt voor de volgende release van .NET. Als u een tag voor een specifieke release wilt selecteren, gebruikt u de Switch branches of tags vervolgkeuzelijst. Zie Een versietag selecteren van ASP.NET Core-broncode (dotnet/AspNetCore.Docs #26205)voor meer informatie.

    Kopieer vanuit de bronmap wwwroot in de app die u hebt gemaakt of op basis van de referentieassets in de dotnet/aspnetcore GitHub-opslagplaats de volgende bestanden naar de map van wwwroot de app:

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

In het wwwroot/index.html-bestand van de app:

  • Voeg elementen toe <link> voor het manifest- en app-pictogram:

    <link href="manifest.json" rel="manifest" />
    <link rel="apple-touch-icon" sizes="512x512" href="icon-512.png" />
    <link rel="apple-touch-icon" sizes="192x192" href="icon-192.png" />
    
  • Voeg de volgende <script> tag toe binnen de afsluitende </body> tag direct na de blazor.webassembly.js scripttag:

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

Installatie- en app-manifest

Wanneer gebruikers een app bezoeken die is gemaakt met behulp van de PWA-sjabloon, hebben gebruikers de mogelijkheid om de app te installeren in het startmenu, dock of startscherm van hun besturingssysteem. De manier waarop deze optie wordt weergegeven, is afhankelijk van de browser van de gebruiker. Wanneer u desktopbrowsers van Chromium gebruikt, zoals Edge of Chrome, wordt er een knop Toevoegen weergegeven in de URL-balk. Nadat de gebruiker de knop Toevoegen heeft geselecteerd, ontvangt deze een bevestigingsdialoogvenster:

In het bevestigingsdialoogvenster in Google Chrome wordt een knop Installeren weergegeven voor de gebruiker voor de app 'MyBlazorPwa'.

In iOS kunnen bezoekers de PWA installeren met de knop Delen van Safari en de optie Toevoegen aan startscherm . In Chrome voor Android moeten gebruikers de menuknop in de rechterbovenhoek selecteren, gevolgd door Toevoegen aan Home scherm.

Nadat de app is geïnstalleerd, wordt deze weergegeven in een eigen venster zonder adresbalk:

De app 'MyBlazorPwa' wordt uitgevoerd in Google Chrome zonder adresbalk.

Als u de titel, het kleurenschema, het pictogram of andere details van het venster wilt aanpassen, raadpleegt u het manifest.json bestand in de map van wwwroot het project. Het schema van dit bestand wordt gedefinieerd door webstandaarden. Zie MDN-webdocumenten voor meer informatie: Web App Manifest.

Offline ondersteuning

Apps die zijn gemaakt met de PWA-sjabloonoptie, bieden ondersteuning voor offline uitvoeren. Een gebruiker moet eerst de app bezoeken terwijl deze online is. De browser downloadt en slaat alle resources die nodig zijn om offline te werken, automatisch in de cache.

Belangrijk

Ontwikkelingsondersteuning zou de gebruikelijke ontwikkelingscyclus verstoren om wijzigingen aan te brengen en te testen. Daarom is offlineondersteuning alleen ingeschakeld voor gepubliceerde apps.

Waarschuwing

Als u van plan bent om een offline-ingeschakelde PWA te distribueren, zijn er verschillende belangrijke waarschuwingen en opmerkingen. Deze scenario's zijn inherent aan offline PWA's en niet specifiek voor Blazor. Lees en begrijp deze opmerkingen voordat u veronderstellingen maakt over de werking van uw offline-app.

Ga als volgt te werk om te zien hoe offlineondersteuning werkt:

  1. Publiceer de app. Zie Host en implementeer ASP.NET Core Blazorvoor meer informatie.

  2. Implementeer de app op een server die HTTPS ondersteunt en open de app in een browser op het beveiligde HTTPS-adres.

  3. Open de ontwikkelhulpprogramma's van de browser en controleer of een Service Worker is geregistreerd voor de host op het tabblad Toepassing :

    Het tabblad 'Toepassing' van Google Chrome-ontwikkelhulpprogramma's toont een geactiveerde en actieve servicemedewerker.

  4. Laad de pagina opnieuw en bekijk het tabblad Netwerk . Service Worker of geheugencache worden vermeld als de bronnen voor alle assets van de pagina:

    Het tabblad Netwerk van Google Chrome-ontwikkelhulpprogramma's met bronnen voor alle assets van de pagina.

  5. Ga als volgt te werk om te controleren of de browser niet afhankelijk is van netwerktoegang om de app te laden:

    • Sluit de webserver af en kijk hoe de app normaal blijft functioneren, waaronder het opnieuw laden van pagina's. Op dezelfde manier blijft de app normaal functioneren wanneer er een trage netwerkverbinding is.
    • Instrueer de browser om de offlinemodus te simuleren op het tabblad Netwerk :

    Het tabblad Netwerk van Google Chrome-ontwikkelhulpprogramma's met de vervolgkeuzelijst in de browsermodus is gewijzigd van 'Online' in 'Offline'.

Offlineondersteuning met behulp van een servicemedewerker is een webstandaard, niet specifiek voor Blazor. Zie MDN-webdocumenten: Service Worker-API voor meer informatie over servicemedewerkers. Zie Google Web: De levenscyclus van servicemedewerkers voor meer informatie over algemene gebruikspatronen voor servicemedewerkers.

BlazorDe PWA-sjabloon produceert twee service worker-bestanden:

  • wwwroot/service-worker.js, die tijdens de ontwikkeling wordt gebruikt.
  • wwwroot/service-worker.published.js, dat wordt gebruikt nadat de app is gepubliceerd.

Als u logica wilt delen tussen de twee service worker-bestanden, moet u rekening houden met de volgende aanpak:

  • Voeg een derde JavaScript-bestand toe om de algemene logica te bewaren.
  • Gebruik self.importScripts om de algemene logica in beide serviceworkerbestanden te laden.

Strategie voor het ophalen van cache-first

De ingebouwde service-worker.published.js servicemedewerker lost aanvragen op met behulp van een cache-first-strategie . Dit betekent dat de servicemedewerker liever inhoud in de cache retourneert, ongeacht of de gebruiker netwerktoegang heeft of nieuwere inhoud beschikbaar is op de server.

De cache-first-strategie is waardevol omdat:

  • Het zorgt voor betrouwbaarheid. Netwerktoegang is geen booleaanse staat. Een gebruiker is niet alleen online of offline:

    • Het apparaat van de gebruiker kan ervan uitgaan dat het online is, maar het netwerk kan zo traag zijn dat het niet praktisch is om te wachten.
    • Het netwerk kan ongeldige resultaten retourneren voor bepaalde URL's, zoals wanneer er een captive WIFI-portal is die momenteel bepaalde aanvragen blokkeert of omleidt.

    Dit is de reden waarom de API van navigator.onLine de browser niet betrouwbaar is en niet afhankelijk mag zijn van.

  • Het zorgt voor juistheid. Bij het bouwen van een cache met offline resources maakt de serviceworker gebruik van content hashing om ervoor te zorgen dat deze een complete en coherente verzameling van resources op een specifiek tijdstip heeft opgehaald. Deze cache wordt vervolgens gebruikt als een atomische eenheid. Er is geen punt om het netwerk te vragen voor nieuwere resources, omdat de enige vereiste versies de versies zijn die al in de cache zijn opgeslagen. Alle andere risico's zijn inconsistentie en incompatibiliteit (bijvoorbeeld het gebruik van versies van .NET-assembly's die niet samen zijn gecompileerd).

Als u wilt voorkomen dat de browser service-worker-assets.js uit de HTTP-cache haalt, bijvoorbeeld om tijdelijke integriteitscontrolefouten op te lossen bij het implementeren van een nieuwe versie van de servicemedewerker, werkt u de registratie van de servicemedewerker in wwwroot/index.html bij met updateViaCache ingesteld op 'geen':

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

Achtergrondupdates

Als mentaal model kunt u een offline-eerste PWA beschouwen als een mobiele app die kan worden geïnstalleerd. De app wordt onmiddellijk gestart, ongeacht de netwerkverbinding, maar de geïnstalleerde app-logica is afkomstig van een momentopname van een bepaald tijdstip dat mogelijk niet de nieuwste versie is.

De Blazor PWA-sjabloon produceert apps die automatisch proberen zichzelf op de achtergrond bij te werken wanneer de gebruiker een werkende netwerkverbinding heeft. Dit werkt als volgt:

  • Tijdens de compilatie genereert het project een manifest voor servicewerkrollen, dat de naam service-worker-assets.jsheeft. Het manifest bevat alle statische resources die de app nodig heeft om offline te werken, zoals .NET-assembly's, JavaScript-bestanden en CSS, inclusief hun inhouds-hashes. De resourcelijst wordt geladen door de servicemedewerker, zodat deze weet welke resources in de cache moeten worden opgeslagen.
  • Telkens wanneer de gebruiker de app bezoekt, vraagt de browser opnieuw service-worker.js en service-worker-assets.js op de achtergrond aan. De bestanden worden byte-voor-byte vergeleken met de bestaande geïnstalleerde service worker. Als de server gewijzigde inhoud voor een van deze bestanden retourneert, probeert de servicemedewerker een nieuwe versie van zichzelf te installeren.
  • Wanneer de servicemedewerker een nieuwe versie van zichzelf installeert, wordt er een nieuwe, afzonderlijke cache voor offlinebronnen gemaakt en wordt de cache gevuld met resources die worden vermeld in service-worker-assets.js. Deze logica wordt geïmplementeerd in de onInstall functie binnen service-worker.published.js.
  • Het proces wordt voltooid wanneer alle resources zonder fouten worden geladen en alle inhoudshashes overeenkomen. Als dit lukt, komt de nieuwe serviceworker in een wachtstatus voor activering. Zodra de gebruiker de app sluit (geen resterende app-tabbladen of vensters), wordt de nieuwe servicemedewerker actief en gebruikt voor volgende app-bezoeken. De oude servicemedewerker en de bijbehorende cache worden verwijderd.
  • Als het proces niet succesvol voltooid is, wordt het nieuwe serviceworker-exemplaar verwijderd. Het updateproces wordt opnieuw geprobeerd bij het volgende bezoek van de gebruiker, wanneer de client hopelijk een betere netwerkverbinding heeft waarmee de aanvragen kunnen worden voltooid.

Pas dit proces aan door de logica van de servicemedewerker te bewerken. Geen van het voorgaande gedrag is specifiek voor Blazor , maar is alleen de standaardervaring die wordt geboden door de PWA-sjabloonoptie. Zie MDN-webdocumenten: Service Worker-API voor meer informatie.

Hoe aanvragen worden opgelost

Zoals beschreven in de sectie Cache-first fetch-strategie , maakt de standaardservicemedewerker gebruik van een cache-first-strategie , wat betekent dat deze inhoud in de cache probeert te verwerken wanneer deze beschikbaar is. Als er geen inhoud in de cache is opgeslagen voor een bepaalde URL, bijvoorbeeld bij het aanvragen van gegevens uit een back-end-API, valt de servicemedewerker terug op een normale netwerkaanvraag. De netwerkaanvraag slaagt als de server bereikbaar is. Deze logica wordt binnen de functie geïmplementeerd onFetchservice-worker.published.js.

Als de onderdelen van Razor de app afhankelijk zijn van het aanvragen van gegevens van back-end-API's en u een beschrijvende gebruikerservaring wilt bieden voor mislukte aanvragen vanwege niet-beschikbaarheid van het netwerk, implementeert u logica binnen de onderdelen van de app. Gebruik bijvoorbeeld try/catch rond HttpClient aanvragen.

Door de server gerenderde pagina's ondersteunen

Bedenk wat er gebeurt wanneer de gebruiker voor het eerst naar een URL navigeert, zoals /counter, of een andere dieptekoppeling in de app. In deze gevallen wilt u geen inhoud die in de cache is opgeslagen als /counter retourneren, maar in plaats daarvan moet de browser de inhoud laden die in de cache is opgeslagen als /index.html om uw Blazor WebAssembly-app te starten. Deze initiële aanvragen worden navigatieaanvragen genoemd, in plaats van:

  • subresource aanvragen voor afbeeldingen, stylesheets of andere bestanden.
  • fetch/XHR API-gegevensaanvragen.

De standaardservicemedewerker bevat speciale logica voor navigatieaanvragen. De serviceworker verwerkt de aanvragen door de opgeslagen inhoud in de cache terug te sturen, ongeacht de aangevraagde URL. Deze logica wordt geïmplementeerd in de onFetch functie binnen service-worker.published.js.

Als uw app bepaalde URL's heeft die server-gerenderde HTML moeten retourneren en niet vanuit de cache moeten worden geleverd /index.html, dan moet u de logica in uw serviceworker aanpassen. Als alle URL's met /Identity/ als reguliere online-only aanvragen naar de server moeten worden verwerkt, moet u de logica van service-worker.published.jsonFetch wijzigen. Zoek de volgende code:

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

Wijzig de code in het volgende:

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

Als u dit niet doet, dan onderschept de serviceworker, ongeacht de netwerkverbinding, aanvragen voor dergelijke URL's en lost deze op met behulp van /index.html.

Voeg extra eindpunten toe voor externe verificatieproviders aan de controle. In het volgende voorbeeld wordt Google-verificatie /signin-google toegevoegd aan de controle:

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

Er is geen actie vereist voor de Development omgeving, waarbij inhoud altijd uit het netwerk wordt opgehaald.

Opslaan van assets in cache beheren

Als uw project de MSBuild-eigenschap ServiceWorkerAssetsManifest definieert, genereert de buildtooling van Blazor een serviceworker-assetsmanifest met de opgegeven naam. De standaard PWA-sjabloon produceert een projectbestand met de volgende eigenschap:

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

Het bestand wordt in de wwwroot uitvoermap geplaatst, zodat de browser dit bestand kan ophalen door het aan te /service-worker-assets.jsvragen. Als u de inhoud van dit bestand wilt zien, opent /bin/Debug/{TARGET FRAMEWORK}/wwwroot/service-worker-assets.js u deze in een teksteditor. Bewerk het bestand echter niet, omdat het opnieuw wordt gegenereerd voor elke build.

De manifestlijst:

  • Alle Blazor-beheerde resources, zoals .NET-assembly's en de .NET WebAssembly-uitvoeringsbestanden die nodig zijn om offline te functioneren.
  • Alle resources voor het publiceren naar de map van wwwroot de app, zoals afbeeldingen, opmaakmodellen en JavaScript-bestanden, inclusief statische webassets die worden geleverd door externe projecten en NuGet-pakketten.

U kunt bepalen welke van deze resources worden opgehaald en in de cache worden opgeslagen door de servicemedewerker door de logica in onInstall te bewerken.service-worker.published.js De service worker haalt bestanden op en plaatst deze in de cache die overeenkomen met typische webbestandsnaamextensies zoals .html, .css, .js en .wasm, plus bestandstypen die specifiek zijn voor Blazor WebAssembly, zoals .pdb-bestanden (alle versies) en .dll-bestanden (ASP.NET Core in .NET 7 of eerder).

Als u extra resources wilt opnemen die niet aanwezig zijn in de map van wwwroot de app, definieert u extra MSBuild-vermeldingen ItemGroup , zoals wordt weergegeven in het volgende voorbeeld:

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

De AssetUrl metagegevens specificeren de basis-relatieve URL die de browser moet gebruiken bij het ophalen van de resource in de cache. Dit kan onafhankelijk zijn van de oorspronkelijke bronbestandsnaam op schijf.

Belangrijk

Als u een ServiceWorkerAssetsManifestItem bestand toevoegt, wordt het niet gepubliceerd in de map van wwwroot de app. De publicatie-uitvoer moet afzonderlijk worden beheerd. De ServiceWorkerAssetsManifestItem zorgt er alleen voor dat er een extra vermelding verschijnt in het assets-manifest van de service worker.

Pushmeldingen

Net als elke andere PWA kan een Blazor WebAssembly PWA pushmeldingen ontvangen van een back-endserver. De server kan op elk gewenst moment pushmeldingen verzenden, zelfs wanneer de gebruiker de app niet actief gebruikt. Pushmeldingen kunnen bijvoorbeeld worden verzonden wanneer een andere gebruiker een relevante actie uitvoert.

Het mechanisme voor het verzenden van een pushmelding is volledig onafhankelijk van Blazor WebAssembly, omdat het wordt geïmplementeerd door de back-endserver die elke technologie kan gebruiken. Als u pushmeldingen van een ASP.NET Core-server wilt verzenden, kunt u overwegen een techniek te gebruiken die vergelijkbaar is met de methode die in de workshop Blazing Pizza wordt gebruikt.

Het mechanisme voor het ontvangen en weergeven van een pushmelding op de client is ook onafhankelijk van Blazor WebAssembly, omdat het is geïmplementeerd in het JavaScript-bestand van de service worker. Zie voor een voorbeeld de benadering die wordt gebruikt in de Blazing Pizza workshop.

Beperkingen voor offline PWA's

Niet alle apps moeten proberen offline gebruik te ondersteunen. Offlineondersteuning voegt een aanzienlijke complexiteit toe, terwijl deze niet altijd relevant is voor de vereiste gebruiksvoorbeelden.

Offlineondersteuning is meestal alleen relevant:

  • Als het primaire gegevensarchief lokaal is in de browser. De benadering is bijvoorbeeld relevant in een app met een gebruikersinterface voor een IoT-apparaat waarin gegevens in localStorage of IndexedDB worden opgeslagen.
  • Als de app een aanzienlijke hoeveelheid werk uitvoert om de back-end-API-gegevens op te halen en op te cachen die relevant zijn voor elke gebruiker, zodat ze offline door de gegevens kunnen navigeren. Als de app ondersteuning moet bieden voor bewerken, moet een systeem voor het bijhouden van wijzigingen en het synchroniseren van gegevens met de back-end worden gebouwd.
  • Als het doel is om te garanderen dat de app onmiddellijk wordt geladen, ongeacht de netwerkomstandigheden. Implementeer een geschikte gebruikerservaring rond back-end-API-aanvragen om de voortgang van aanvragen weer te geven en zich probleemloos te gedragen wanneer aanvragen mislukken vanwege niet-beschikbaarheid van het netwerk.

Bovendien moeten offline geschikte PWA's een reeks extra complicaties afhandelen. Ontwikkelaars moeten zich zorgvuldig vertrouwd maken met de opmerkingen in de volgende secties.

Offlineondersteuning alleen wanneer deze wordt gepubliceerd

Tijdens de ontwikkeling wilt u meestal elke wijziging direct in de browser zien zonder een achtergrondupdateproces te doorlopen. BlazorDaarom schakelt de PWA-sjabloon alleen offlineondersteuning in wanneer deze wordt gepubliceerd.

Wanneer u een offline-compatibele app bouwt, is het niet voldoende om de app in de Development omgeving te testen. U moet de app in de gepubliceerde status testen om te begrijpen hoe deze reageert op verschillende netwerkvoorwaarden.

Nadat de gebruiker de app verlaat, wordt de update voltooid.

Updates worden pas voltooid als de gebruiker de app heeft verlaten op alle tabbladen. Zoals uitgelegd in de sectie Updates op de achtergrond , haalt de browser, nadat u een update naar de app hebt geïmplementeerd, de bijgewerkte service worker-bestanden op om het updateproces te starten.

Wat veel ontwikkelaars verrast is dat, zelfs wanneer deze update is voltooid, deze pas van kracht wordt nadat de gebruiker op alle tabbladen is genavigeerd. Het is niet voldoende om het tabblad te vernieuwen dat de app weergeeft, zelfs als het het enige tabblad is dat de app weergeeft. Totdat uw app volledig is gesloten, blijft de nieuwe servicemedewerker in de wacht om de status te activeren . Dit is niet specifiek voor Blazor, maar is eerder een standaardgedrag van het webplatform.

Ontwikkelaars hebben hier vaak moeite mee als ze proberen updates voor hun serviceworker of offline opgeslagen resources te testen. Als u de ontwikkelhulpprogramma's van de browser inschakelt, ziet u mogelijk iets als het volgende:

Op het tabblad 'Toepassing' van Google Chrome ziet u dat de servicemedewerker van de app wacht op activeren.

Zolang de lijst met 'clients', die tabbladen of vensters zijn waarin uw app wordt weergegeven, niet leeg is, blijft de worker wachten. De reden waarom servicemedewerkers dit doen, is om consistentie te garanderen. Consistentie betekent dat alle resources worden opgehaald uit dezelfde atomische cache.

Wanneer u wijzigingen test, is het wellicht handig om de koppeling 'skipWaiting' te selecteren, zoals wordt weergegeven in de vorige schermopname, en vervolgens de pagina opnieuw te laden. U kunt dit voor alle gebruikers automatiseren door uw servicemedewerker te coderen om de 'wachtfase' over te slaan en onmiddellijk te activeren bij de update. Als u de wachtfase overslaat, geeft u de garantie op dat resources altijd consistent worden opgehaald uit hetzelfde cache-exemplaar.

Gebruikers kunnen elke historische versie van de app uitvoeren

Webontwikkelaars verwachten normaal dat gebruikers alleen de meest recente geïmplementeerde versie van hun web-app uitvoeren, omdat dat normaal is binnen het traditionele webdistributiemodel. Een offline-first PWA is echter meer verwant aan een systeemeigen mobiele app, waarbij gebruikers niet noodzakelijkerwijs de nieuwste versie uitvoeren.

Zoals uitgelegd in de sectie Achtergrondupdates , blijft elke bestaande gebruiker na het implementeren van een update in uw app een eerdere versie gebruiken voor ten minste één bezoek, omdat de update op de achtergrond plaatsvindt en pas wordt geactiveerd nadat de gebruiker daarna weg navigeert. Bovendien is de vorige versie die wordt gebruikt niet noodzakelijkerwijs de vorige versie die u hebt geïmplementeerd. De vorige versie kan elke historische versie zijn, afhankelijk van wanneer de gebruiker een update voor het laatst heeft voltooid.

Dit kan een probleem zijn als de front-end- en back-endonderdelen van uw app een overeenkomst vereisen over het schema voor API-aanvragen. U moet pas achterwaarts incompatibele API-schemawijzigingen implementeren als u zeker weet dat alle gebruikers een upgrade hebben uitgevoerd. U kunt ook voorkomen dat gebruikers incompatibele oudere versies van de app gebruiken. Deze scenariovereiste is hetzelfde als voor systeemeigen mobiele apps. Als u een belangrijke wijziging in server-API's implementeert, wordt de client-app verbroken voor gebruikers die nog niet zijn bijgewerkt.

Implementeer indien mogelijk geen belangrijke wijzigingen in uw back-end-API's. Als u dit moet doen, kunt u overwegen om standaard Service Worker-API's zoals ServiceWorkerRegistration te gebruiken om te bepalen of de app up-to-datum is en zo niet, om gebruik te voorkomen.

Interferentie met door de server gerenderde pagina's

Zoals beschreven in de sectie Server-gerenderde pagina's ondersteunen, bewerkt u de logica in uw serviceworker als u het gedrag van de serviceworker voor het retourneren /index.html van inhoud voor alle navigatieaanvragen wilt omzeilen.

Alle inhoud van het assetmanifest van de service worker wordt in de cache opgeslagen

Zoals beschreven in de sectie Controle van asset caching, wordt het bestand service-worker-assets.js gegenereerd tijdens het bouwen en vermeldt alle assets die de serviceworker moet ophalen en cachen.

Aangezien deze lijst alles bevat waarnaar wordt verzonden wwwroot, inclusief inhoud die wordt geleverd door externe pakketten en projecten, moet u er niet te veel inhoud in plaatsen. Als de wwwroot map miljoenen afbeeldingen bevat, probeert de serviceworker ze allemaal op te halen en in de cache op te slaan, waardoor er overmatig bandbreedte wordt verbruikt en de taak waarschijnlijk niet succesvol wordt afgerond.

Implementeer willekeurige logica om te bepalen in welke subset van de inhoud van het manifest moet worden opgehaald en opgeslagen in de cache door de onInstall functie in service-worker.published.jste bewerken.

Interactie met verificatie

De PWA-sjabloon kan worden gebruikt in combinatie met verificatie. Een offline-compatibele PWA kan ook verificatie ondersteunen wanneer de gebruiker de initiële netwerkverbinding heeft.

Wanneer een gebruiker geen netwerkverbinding heeft, kan deze geen toegangstokens verifiëren of verkrijgen. Als u de aanmeldingspagina zonder netwerktoegang probeert te bezoeken, wordt het bericht 'netwerkfout' weergegeven. U moet een UI-stroom ontwerpen waarmee de gebruiker nuttige taken kan uitvoeren terwijl deze offline is zonder de gebruiker te verifiëren of toegangstokens te verkrijgen. U kunt de app ook ontwerpen om probleemloos te mislukken wanneer het netwerk niet beschikbaar is. Als de app niet kan worden ontworpen voor het afhandelen van deze scenario's, wilt u mogelijk geen offlineondersteuning inschakelen.

Wanneer een app die is ontworpen voor online en offline gebruik weer online is:

  • Mogelijk moet de app een nieuw toegangstoken inrichten.
  • De app moet detecteren of een andere gebruiker is aangemeld bij de service, zodat bewerkingen kunnen worden toegepast op het account van de gebruiker dat is gemaakt terwijl ze offline waren.

Een offline PWA-app maken die communiceert met verificatie:

  • Vervang de AccountClaimsPrincipalFactory<TAccount> door een fabriek waarin de laatst aangemelde gebruiker wordt opgeslagen en die de opgeslagen gebruiker gebruikt wanneer de app offline is.
  • Plaats handelingen in de wachtrij terwijl de app offline is en pas ze toe wanneer de app weer online is.
  • Bij het afmelden, wis de opgeslagen gebruiker.

De CarChecker voorbeeld-app demonstreert de voorgaande benaderingen. Zie de volgende onderdelen van de app:

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

Aanvullende bronnen

Aan clientzijde SignalR cross-origin-onderhandeling voor authenticatie