Gestione delle richieste di navigazione

Rispondi alle richieste di navigazione senza attendere sulla 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 in una pagina che rimanda a un nuovo URL. È qui che i service worker hanno il massimo impatto sulle prestazioni: se utilizzi un service worker per rispondere alle richieste di navigazione senza attendere la rete, puoi assicurarti che le navigazioni siano rapide in modo affidabile, oltre a essere resilienti quando la rete non è disponibile. Questo è il principale vantaggio in termini di prestazioni offerto da un service worker, rispetto a quanto possibile con la memorizzazione nella cache HTTP.

Come descritto in dettaglio nella guida Identificare le risorse caricate dalla rete, una richiesta di navigazione è la prima di potenzialmente numerose richieste effettuate nella "struttura a cascata" del traffico di rete. Il codice HTML caricato tramite una richiesta di navigazione avvia il flusso di tutte le altre richieste per le 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 in FetchEvent. Se è impostato su 'navigate', si tratta di una richiesta di navigazione.

Come regola generale, non utilizzare Cache-Control headers di lunga durata per memorizzare nella cache la risposta HTML per una richiesta di navigazione. Di solito devono essere soddisfatti tramite la rete, con Cache-Control: no-cache, per garantire che l'HTML, insieme alla catena delle successive richieste di rete, sia (ragionevolmente) aggiornato. Sfortunatamente, andare contro la rete ogni volta che l'utente accede a una nuova pagina significa che ogni navigazione potrebbe essere lenta. Per lo meno, ciò significa che non sarà affidabile veloce.

Approcci diversi per le architetture

Capire come rispondere alle richieste di navigazione evitando la rete può essere complicato. L'approccio giusto dipende molto dall'architettura del tuo sito web e dal numero di URL univoci a cui gli utenti potrebbero accedere.

Anche se non esiste una soluzione universale, le seguenti linee guida generali dovrebbero aiutarti a decidere quale approccio è il più attuabile.

Siti statici di piccole dimensioni

Se la tua applicazione web è costituita da un numero relativamente ridotto (ad esempio, due dozzine) di URL univoci e ciascuno di questi URL corrisponde a un file HTML statico diverso, un approccio possibile è memorizzare nella cache tutti questi file HTML e rispondere alle richieste di navigazione con il codice HTML appropriato memorizzato nella cache.

Con la pre-memorizzazione nella cache puoi memorizzare nella cache il codice HTML in anticipo, non appena il Service worker viene installato, e aggiornare il codice HTML memorizzato nella cache ogni volta che ricrei il sito e riesegui il deployment del Service worker.

In alternativa, se preferisci evitare la pre-memorizzazione nella cache di tutto il codice HTML, forse perché gli utenti tendono a accedere solo a un sottoinsieme di URL sul tuo sito, puoi utilizzare una strategia di memorizzazione nella cache di runtime stale-what-revalidate. 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 spesso dallo stesso insieme di utenti e se preferisci che questi URL vengano riconvalidati in modo indipendente l'uno dall'altro.

App di una sola pagina

Un'architettura a pagina singola è spesso utilizzata dalle applicazioni web moderne. al suo interno, il codice JavaScript lato client modifica l'HTML in risposta alle azioni dell'utente. Questo modello utilizza l'API History per modificare l'URL corrente mentre l'utente interagisce con l'app web, generando effettivamente una navigazione "simulata". Anche se le navigazioni successive potrebbero essere "false", la navigazione iniziale è reale ed è comunque importante assicurarti che non sia bloccata sulla rete.

Fortunatamente, se utilizzi l'architettura a pagina singola, per gestire la navigazione iniziale dalla cache esiste un semplice pattern da seguire: la shell dell'applicazione. In questo modello, il service worker risponde alle richieste di navigazione restituendo lo stesso singolo file HTML che è già stato prememorizzato nella cache, indipendentemente dall'URL richiesto. Questo codice HTML deve essere essenziale e consistere, forse, di un indicatore di caricamento generico o di uno scheletro di contenuti. Una volta che il browser ha caricato questo codice HTML dalla cache, il codice JavaScript lato client esistente prende il comando e visualizza i contenuti HTML corretti per l'URL della richiesta di navigazione originale.

Workbox fornisce gli strumenti necessari per implementare questo approccio. navigateFallback option ti consente di specificare il documento HTML da utilizzare come shell dell'app, insieme a un elenco facoltativo di autorizzazione e autorizzazione per limitare questo comportamento a un sottoinsieme di URL.

App multipagina

Se il server web genera il codice 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. È probabile che il consiglio della sezione Tutto il resto riguardi anche te.

Tuttavia, per un determinato sottoinsieme di app con più pagine, potresti essere in grado di implementare un service worker che replica completamente la logica utilizzata nel server web per generare l'HTML. Questa opzione funziona al meglio se puoi condividere le informazioni di routing e modelli tra gli ambienti server e service worker e, in particolare, se il 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 tuo service worker, puoi consultare le indicazioni riportate in Beyond SPA: architetture alternative per la tua PWA possono aiutarti a iniziare.

Tutto il resto

Se non riesci a rispondere alle richieste di navigazione con il codice HTML memorizzato nella cache, devi adottare misure per garantire che l'aggiunta di un service worker al tuo sito (per gestire altre richieste non HTML) non rallenti le tue navigazioni. L'avvio del service worker senza utilizzarlo per rispondere a una richiesta di navigazione introdurrà una piccola quantità di latenza (come spiegato in Creare app più veloci e più resilienti con Service Worker). Per mitigare questo overhead, attiva una funzionalità chiamata precaricamento della navigazione e utilizza la risposta di rete precaricata all'interno del gestore di eventi fetch.

Workbox fornisce una libreria helper che la funzionalità rileva se il precaricamento della navigazione è supportato e, in questo caso, semplifica il processo per informare il tuo service worker di utilizzare la risposta di rete.

Foto di Aaron Burden su Unsplash