Rispondi alle richieste di navigazione senza attendere la rete utilizzando un service worker.
Le richieste di navigazione sono richieste di documenti HTML effettuate dal browser ogni volta che inserisci un nuovo URL nella barra di navigazione o segui un link su una pagina che ti indirizza a un nuovo URL. È qui che i service worker hanno il maggiore impatto sulle prestazioni: se utilizzi un service worker per rispondere alle richieste di navigazione senza attendere la rete, puoi assicurarti che le navigazioni siano sempre veloci, oltre a essere resilienti quando la rete non è disponibile. Questo è il più grande vantaggio in termini di prestazioni che deriva da un service worker rispetto a ciò che è possibile fare con la memorizzazione nella cache HTTP.
Come descritto nella guida Identifica le risorse caricate dalla rete, una richiesta di navigazione è la prima di potenzialmente molte richieste effettuate nella "cascata" del traffico di rete. L'HTML che carichi tramite una richiesta di navigazione avvia il flusso di tutte le altre richieste di risorse secondarie come immagini, script e stili.
All'interno del gestore di eventi fetch di un service worker, puoi determinare se una richiesta è una navigazione controllando la proprietà request.mode su FetchEvent. Se è impostato su 'navigate', si tratta di una richiesta di navigazione.
In linea generale, non utilizzare Cache-Control headers di lunga durata per memorizzare nella cache la risposta HTML per una richiesta di navigazione. In genere, devono essere soddisfatte tramite la rete, con Cache-Control: no-cache, per garantire che l'HTML, insieme alla catena di richieste di rete successive, sia (ragionevolmente) aggiornato. Purtroppo, l'accesso alla rete ogni volta che l'utente passa a una nuova pagina significa che ogni navigazione potrebbe essere lenta. Come minimo, significa che non sarà sempre veloce.
Approcci diversi per le architetture
Capire come rispondere alle richieste di navigazione evitando la rete può essere difficile. L'approccio giusto dipende molto dall'architettura del tuo sito web e dal numero di URL univoci a cui gli utenti potrebbero accedere.
Sebbene non esista una soluzione valida per tutti, le seguenti linee guida generali dovrebbero aiutarti a decidere quale approccio è più fattibile.
Siti statici di piccole dimensioni
Se la tua app web è costituita da un numero relativamente ridotto (ad esempio un paio di decine) di URL univoci e ognuno di questi URL corrisponde a un file HTML statico diverso, un approccio praticabile è memorizzare nella cache tutti questi file HTML e rispondere alle richieste di navigazione con l'HTML memorizzato nella cache appropriato.
Utilizzando il pre-caching, puoi memorizzare nella cache l'HTML in anticipo, non appena il service worker viene installato, e aggiornare l'HTML memorizzato nella cache ogni volta che ricostruisci il sito e rifai il deployment del service worker.
In alternativa, se preferisci evitare di pre-memorizzare nella cache tutto il codice HTML, ad esempio perché gli utenti tendono a navigare solo in un sottoinsieme di URL del tuo sito, puoi utilizzare una strategia di memorizzazione nella cache di runtime stale-while-revalidate. Tuttavia, fai attenzione a questo approccio, poiché ogni singolo documento HTML viene memorizzato nella cache e aggiornato separatamente. L'utilizzo della memorizzazione nella cache di runtime per l'HTML è più appropriato se hai un numero ridotto di URL che vengono rivisitati frequentemente dallo stesso insieme di utenti e se non hai problemi con la convalida di questi URL in modo indipendente l'uno dall'altro.
App a pagina singola
Un'architettura a pagina singola viene spesso utilizzata dalle applicazioni web moderne. In questo caso, il codice JavaScript lato client modifica il codice HTML in risposta alle azioni dell'utente. Questo modello utilizza l'API History per modificare l'URL corrente quando l'utente interagisce con l'app web, il che porta a una navigazione "simulata". Anche se le navigazioni successive potrebbero essere "fittizie", la navigazione iniziale è reale ed è comunque importante assicurarsi che non sia bloccata sulla rete.
Fortunatamente, se utilizzi l'architettura a pagina singola, esiste un pattern semplice da seguire per pubblicare la navigazione iniziale dalla cache: la shell dell'applicazione. In questo modello, il service worker risponde alle richieste di navigazione restituendo lo stesso singolo file HTML che è già stato memorizzato nella pre-cache, indipendentemente dall'URL richiesto. Questo codice HTML deve essere essenziale e composto, ad esempio, da un indicatore di caricamento generico o da contenuti scheletro. Una volta che il browser ha caricato questo codice HTML dalla cache, il codice JavaScript lato client esistente prende il sopravvento ed esegue il rendering dei contenuti HTML corretti per l'URL dalla richiesta di navigazione originale.
Workbox fornisce gli strumenti necessari per implementare questo approccio; navigateFallback
option
ti consente di specificare quale documento HTML utilizzare come shell dell'app, insieme a un elenco facoltativo di elementi consentiti e
bloccati per limitare questo comportamento a un sottoinsieme dei tuoi URL.
App multipagina
Se il tuo server web genera l'HTML del tuo sito in modo dinamico o se hai più di qualche decina di pagine uniche, è molto più difficile evitare la rete quando gestisci le richieste di navigazione. I consigli riportati nella sezione Tutto il resto probabilmente si applicano al tuo caso.
Tuttavia, per un determinato sottoinsieme di app multipagina, potresti essere in grado di implementare un service worker che replica completamente la logica utilizzata nel tuo server web per generare l'HTML. Questo approccio funziona meglio se puoi condividere le informazioni di routing e dei modelli tra gli ambienti del server e del service worker e, in particolare, se il tuo server web utilizza JavaScript (senza fare affidamento su funzionalità specifiche di Node.js, come l'accesso al file system).
Se il tuo server web rientra in questa categoria e vuoi esplorare un approccio per spostare la generazione di HTML dalla rete al service worker, puoi iniziare con le indicazioni riportate in Oltre le SPA: architetture alternative per la tua PWA.
Tutto il resto
Se non puoi rispondere alle richieste di navigazione con l'HTML memorizzato nella cache, devi adottare misure per assicurarti che l'aggiunta di un service worker al tuo sito (per gestire altre richieste non HTML) non rallenti le navigazioni. L'avvio del service worker senza utilizzarlo per rispondere a una richiesta di navigazione introdurrà una piccola quantità di latenza (come spiegato in Creazione di app più veloci e resilienti con il service worker). Puoi ridurre questo overhead attivando una funzionalità chiamata precaricamento della navigazione e poi utilizzando la risposta di rete precaricata all'interno del gestore di eventi fetch.
Workbox fornisce una libreria di supporto che rileva se il precaricamento della navigazione è supportato e, in caso affermativo, semplifica il processo di comunicazione al service worker di utilizzare la risposta di rete.