La progettazione dell'applicazione in modo da ottenere il massimo dalla tecnologia che rende affidabili, installabili e capaci le PWA inizia con la comprensione dell'applicazione e i suoi vincoli, per poi scegliere un'architettura appropriata per entrambe.
SPA e MPA
Oggi esistono due modelli architetturali principali nello sviluppo web: le app a pagina singola, o APS, e le app a più pagine, o MPA.
Per app con una sola pagina, il codice JavaScript lato client controlla gran parte o tutto il rendering HTML di una pagina in base ai dati recuperati o forniti dall'app. L'app sostituisce la navigazione integrata nel browser, sostituendola con le funzionalità di gestione del routing e della gestione delle visualizzazioni.
In genere, le app con più pagine presentano codice HTML pre-renderizzato inviato direttamente al browser, spesso migliorato con il codice JavaScript lato client dopo che il browser ha terminato il caricamento dell'HTML e facendo affidamento sui meccanismi di navigazione integrati del browser per visualizzare le visualizzazioni successive.
Entrambe le architetture possono essere utilizzate per creare PWA.
Ognuna presenta vantaggi e svantaggi ed è fondamentale scegliere quella giusta per il caso d'uso e il contesto in uso, per offrire agli utenti un'esperienza veloce e affidabile.
App a pagina singola
- Aggiornamenti in-page prevalentemente atomici.
- Dipendenze lato client caricate all'avvio.
- I caricamenti successivi sono veloci, a causa dell'utilizzo della cache.
- Costo di caricamento iniziale elevato.
- Le prestazioni dipendono dall'hardware del dispositivo e dalla connessione di rete.
- È necessaria un'ulteriore complessità dell'app.
Le app a pagina singola si adattano perfettamente all'architettura se:
- L'interazione degli utenti è incentrata principalmente sugli aggiornamenti atomici dei dati interconnessi visualizzati sulla stessa pagina, ad esempio una dashboard di dati in tempo reale o un'app di modifica video.
- L'applicazione ha dipendenze di inizializzazione solo lato client, ad esempio un provider di autenticazione di terze parti con un costo di avvio proibitivo elevato.
- I dati necessari per il caricamento di una vista si basano su un contesto specifico solo lato client, ad esempio la visualizzazione dei controlli per un componente hardware collegato.
- L'app è abbastanza piccola e semplice che le sue dimensioni e complessità non hanno un impatto sui contro elencati sopra.
Le APS potrebbero non essere una buona scelta di architettura se:
- Le prestazioni del caricamento iniziale sono essenziali. In genere, le APS devono caricare più JavaScript per determinare cosa caricare e come visualizzarlo. I tempi di analisi e di esecuzione di questo codice JavaScript, combinati con il recupero dei contenuti, sono più lenti rispetto all'invio del codice HTML visualizzato.
- L'app funziona principalmente su dispositivi con potenza scarsa o media. Poiché le APS dipendono da JavaScript per il rendering, l'esperienza utente dipende in modo molto più significativo dalla potenza del dispositivo specifico rispetto a una MPA.
Poiché le APS devono sostituire la navigazione integrata del browser con il relativo routing, le APS richiedono un livello minimo di complessità nell'aggiornamento efficiente della vista corrente, nella gestione delle modifiche alla navigazione e nella pulizia delle visualizzazioni precedenti che altrimenti sarebbero gestite dal browser, rendendole più difficili da gestire nel complesso e più gravose per il dispositivo dell'utente.
App con più pagine
- In genere aggiornamenti a pagina intera.
- La velocità di rendering iniziale è fondamentale.
- Lo scripting lato client può essere un miglioramento.
- Le viste secondarie richiedono un'altra chiamata al server.
- Il contesto non viene trasferito da una visualizzazione all'altra.
- Richiede un server o un pre-rendering.
Le app con più pagine sono una buona scelta a livello di architettura se:
- L'interazione degli utenti è incentrata principalmente sulle visualizzazioni di un singolo dato con dati facoltativi basati sul contesto, ad esempio un'app di notizie o di e-commerce.
- La velocità di rendering iniziale è fondamentale, poiché l'invio al browser dell'HTML già visualizzato è più veloce rispetto all'assemblaggio da una richiesta di dati dopo il caricamento, l'analisi e l'esecuzione di un'alternativa basata su JavaScript.
- L'interattività o il contesto lato client possono essere inclusi come miglioramento dopo il caricamento iniziale, ad esempio l'integrazione di un profilo su una pagina visualizzata o l'aggiunta di componenti secondari dipendenti dal contesto sul lato client.
Gli MPA potrebbero non essere una buona scelta di architettura se:
- Scaricare di nuovo, analizzare ed eseguire nuovamente il codice JavaScript o CSS è costoso in modo proibitivo. Questo problema è ridotto nelle PWA con i service worker.
- Il contesto lato client, ad esempio la posizione dell'utente, non va da una visualizzazione all'altra, e riottenere questo contesto potrebbe essere costoso. Deve essere acquisito e recuperato oppure richiesto nuovamente tra una visualizzazione e l'altra.
Perché le singole viste devono essere sottoposte a rendering dinamico da un server o sottoposte a pre-rendering prima dell'accesso, il che potrebbe limitare l'hosting o aggiungere complessità ai dati.
Quale scegliere?
Anche con questi pro e contro, entrambe le architetture sono valide per creare la tua PWA. Puoi anche combinarli per parti diverse della tua app, a seconda delle sue esigenze, ad esempio fare in modo che le schede dello Store seguano un'architettura MPA e il flusso di pagamento segua un'architettura SPA.
Indipendentemente dalla scelta, il passaggio successivo è capire come utilizzare al meglio i service worker per offrire la migliore esperienza.
La potenza del service worker
Il service worker ha molta potenza oltre all'instradamento di base e all'invio delle risposte di rete e memorizzate nella cache. Possiamo creare algoritmi complessi in grado di migliorare l'esperienza e le prestazioni dell'utente.
Service worker include (SWI)
Un modello emergente per l'utilizzo dei service worker come parte integrante dell'architettura di un sito è il Service worker include (SWI). SWI suddivide i singoli asset, in genere una pagina HTML, in pezzi in base alle relative esigenze di memorizzazione nella cache, quindi li unisce nuovamente nel service worker per migliorare coerenza, prestazioni e affidabilità, riducendo al contempo le dimensioni della cache.
Questa immagine è una pagina web di esempio. La pagina è suddivisa in cinque diverse sezioni:
- Layout generale.
- Intestazione globale (barra scura in alto).
- Area dei contenuti (righe centrali a sinistra e immagine).
- Barra laterale (barra alta medio-scura al centro a destra).
- Piè di pagina (barra inferiore scura).
Layout generale
Non è probabile che il layout generale cambi spesso e non abbia dipendenze. È un buon candidato per la precache.
Titolo e piè di pagina
L'intestazione e il piè di pagina globali, ad esempio, contengono elementi come il menu principale e il piè di pagina del sito e presentano un problema particolare: se la pagina dovesse essere interamente memorizzata nella cache, potrebbero cambiare durante il caricamento della pagina, in base a quando la pagina è stata memorizzata nella cache.
Separandole e memorizzandole nella cache indipendentemente dai contenuti, puoi assicurarti che gli utenti ricevano sempre la stessa versione, indipendentemente da quando sono memorizzate nella cache. Poiché vengono aggiornati di rado, sono anche ottimi candidati per la memorizzazione nella cache. Hanno però una dipendenza: dal CSS e da JavaScript del sito.
CSS e JavaScript
Idealmente, il codice CSS e JavaScript del sito dovrebbero essere memorizzati nella cache in modo che non risultino aggiornati mentre la strategia di riconvalida consente aggiornamenti incrementali senza dover aggiornare il service worker, come nel caso degli asset pre-memorizzati nella cache. Tuttavia, è necessario mantenere la versione minima anche ogni volta che il service worker viene aggiornato con una nuova intestazione o piè di pagina globale. Per questo motivo, anche la cache deve essere aggiornata con l'ultima versione degli asset al momento dell'installazione del service worker.
Area dei contenuti
Poi c'è l'area dei contenuti. A seconda della frequenza degli aggiornamenti, in questi casi è consigliabile utilizzare prima la rete o i dati inattivi mentre la riconvalida è una buona strategia. Le immagini devono essere memorizzate nella cache con una strategia basata sulla cache, come discusso in precedenza.
Barra laterale
Infine, se i contenuti della barra laterale includono contenuti secondari, come tag ed elementi correlati, non è abbastanza importante per essere estratti dalla rete. Una strategia di riconvalida obsoleta è valida per questo caso.
Ora, dopo avere fatto tutto questo, potreste pensare che è possibile eseguire questo tipo di memorizzazione nella cache per sezione solo per le app a pagina singola. Tuttavia, adottando pattern ispirati agli inclusioni lato server o alle inclusioni lato server nel tuo service worker, con alcune funzionalità avanzate dei service worker, puoi farlo per entrambe le architetture.
Fai una prova
Puoi provare a includere il service worker nel codelab successivo:
Risposte dinamiche
La pagina precedente potrebbe essere creata utilizzando il modello shell dell'app nel mondo SPA, in cui la shell dell'app viene memorizzata nella cache e poi pubblicata e i contenuti vengono caricati sul lato client. Con l'introduzione e l'ampia disponibilità dell'API Streams, sia la shell dell'app che i contenuti possono essere combinati nel service worker e trasmessi in streaming al browser, offrendo la flessibilità della memorizzazione nella cache della shell dell'app con la velocità degli MPA.
Perché:
- Gli stream possono essere creati in modo asincrono, consentendo alle diverse parti di uno stream di provenire da altre origini.
- Il richiedente di un flusso può iniziare a lavorare sulla risposta non appena è disponibile il primo blocco di dati, invece di attendere il completamento dell'intero elemento.
- Gli analizzatori ottimizzati per lo streaming, compreso il browser, possono visualizzare progressivamente i contenuti dello stream prima che sia completo, accelerando le prestazioni percepite della risposta.
Grazie a queste tre proprietà degli stream, le architetture basate sullo streaming di solito hanno prestazioni percepite più rapidamente di quelle che non lo sono.
Lavorare con l'API Streams può essere impegnativo perché è complesso e di basso livello. Fortunatamente, è disponibile un modulo Casella di lavoro che può essere utile per la configurazione delle risposte dinamiche per i service worker.
Domini, origini e ambito PWA
I web worker, inclusi i service worker, lo spazio di archiviazione e la finestra di una PWA installata, sono tutti regolati da uno dei meccanismi di sicurezza più critici sul web: il criterio della stessa origine. All'interno della stessa origine, vengono concesse le autorizzazioni, i dati possono essere condivisi e il service worker può comunicare con diversi client. Al di fuori della stessa origine, le autorizzazioni non vengono concesse automaticamente e i dati sono isolati e non accessibili tra origini diverse.
Criterio della stessa origine
Due URL indicano che hanno l'origine esatta se il protocollo, la porta e l'host sono gli stessi.
Ad esempio: https://squoosh.app
e https://squoosh.app/v2
hanno la stessa origine, ma http://squoosh.app
, https://squoosh.com
, https://app.squoosh.app
e https://squoosh.app:8080
hanno origini diverse. Per ulteriori informazioni ed esempi, consulta il riferimento MDN del criterio della stessa origine.
La modifica dei sottodomini non è l'unico modo in cui un host può cambiare. Ciascun host è costituito da un dominio di primo livello (TLD), da un dominio di livello secondario (SLD) e da una o più etichette (a volte chiamate sottodomini), separate da punti e lette da destra a sinistra in un URL. Una modifica in uno degli elementi cambia l'host.
Nel modulo di gestione delle finestre, abbiamo già visto l'aspetto del browser in-app quando un utente passa a un'origine diversa da una PWA installata.
Il browser in-app verrà visualizzato anche se i siti web hanno lo stesso TLD e SLD, ma con etichette diverse, in quanto vengono considerati origini diverse.
Uno degli aspetti fondamentali di un'origine in un contesto di navigazione sul web è il funzionamento dello spazio di archiviazione e delle autorizzazioni. Un'origine condivide molte funzionalità con tutti i contenuti e le PWA al suo interno, tra cui:
- Quota di archiviazione e dati (IndexedDB, cookie, archiviazione web, archiviazione nella cache).
- Registrazioni dei service worker.
- Autorizzazioni concesse o negate (ad esempio web push, geolocalizzazione, sensori).
- Registrazioni push web.
Quando passi da un'origine a un'altra, tutto l'accesso precedente viene revocato, quindi le autorizzazioni devono essere concesse di nuovo e la PWA non può accedere a tutti i dati salvati nello spazio di archiviazione.