Rispondere alle richieste di navigazione senza attendere sulla rete utilizzando un servizio 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 ti reindirizza 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 affidabili e rapide, oltre che essere resilienti quando la rete non è disponibile. Si tratta del maggiore miglioramento delle prestazioni offerto da un service worker rispetto a quanto è possibile con la cache HTTP.
Come descritto nella guida Identificare le risorse caricate dalla rete, una richiesta di navigazione è la prima di potenzialmente molte richieste effettuate nella "cascata" del traffico di rete. Il codice HTML caricato 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 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
a lungo termine per memorizzare nella cache la risposta HTML per una richiesta di navigazione. Normalmente dovrebbero essere soddisfatti tramite la rete, conCache-Control: no-cache
, per garantire che il codice HTML, insieme alla catena di richieste di rete successive, sia (ragionevolmente) aggiornato. Andare contro la rete ogni volta che l'utente passa a una nuova pagina purtroppo significa che ogni navigazione potrebbe essere lenta. Per lo meno, significa che non sarà affidabile.
Approcci diversi per le architetture
Capire come rispondere alle richieste di navigazione evitando la rete può essere complicato. L'approccio corretto 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 unica per tutti, le seguenti linee guida generali dovrebbero aiutarti a decidere qual è l'approccio più pratico.
Piccoli siti statici
Se la tua app web è composta da un numero relativamente ridotto (ad esempio una ventina) di URL univoci e ciascuno di questi URL corrisponde a un file HTML statico diverso, un approccio valido è semplicemente memorizzare nella cache tutti questi file HTML e rispondere alle richieste di navigazione con il codice HTML memorizzato nella cache appropriato.
Con il precaching, puoi memorizzare in cache l'HTML in anticipo, non appena viene installato il servizio worker, e aggiornare l'HTML memorizzato nella cache ogni volta che ricostruisci il sito e reimplementi il servizio worker.
In alternativa, se preferisci evitare di eseguire il precaching di tutto il codice HTML, ad esempio perché gli utenti tendono a visitare solo un sottoinsieme di URL sul tuo sito, puoi utilizzare una strategia di memorizzazione nella cache di runtime non valida durante la convalida. 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 HTML è più appropriato se hai un numero ridotto di URL che vengono visitati spesso dallo stesso gruppo di utenti e se ritieni che la convalida di questi URL sia indipendente l'una dall'altra.
App a pagina singola
Le applicazioni web moderne utilizzano spesso un'architettura a pagina singola. 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, generando una navigazione "simulata". Anche se le navigazioni successive potrebbero essere "false", 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 servizio worker risponde alle richieste di navigazione restituendo lo stesso singolo file HTML che è stato già precaricato, indipendentemente dall'URL richiesto. Questo codice HTML deve essere essenziale, costituito, ad esempio, da un indicatore di caricamento generico o da contenuti di base. Una volta che il browser ha caricato questo codice HTML dalla cache, il codice JavaScript lato client esistente prende il controllo 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 URL consentiti e vietati per limitare questo comportamento a un sottoinsieme di URL.
App a più pagine
Se il tuo server web genera il codice HTML del tuo sito in modo dinamico o se hai più di alcune dozzine di pagine uniche, è molto più difficile evitare la rete durante la gestione delle richieste di navigazione. È probabile che i consigli riportati nella sezione Tutto il resto ti riguardino.
Tuttavia, per un determinato sottoinsieme di app multipagina, potresti essere in grado di implementare un service worker che replichi completamente la logica utilizzata nel server web per generare HTML. Questo metodo funziona meglio se puoi condividere informazioni di routing e creazione di modelli tra gli ambienti del server e del worker di servizio 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 tuo service worker, le indicazioni riportate in Oltre le SPA: architetture alternative per le tue PWA possono aiutarti a iniziare.
Tutto il resto
Se non riesci a rispondere alle richieste di navigazione con 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 finisca per rallentare le navigazioni. L'avvio del service worker senza utilizzarlo per rispondere a una richiesta di navigazione introdurrà una piccola latenza (come spiegato in Creare app più veloci e resilienti con i service worker). Puoi ridurre questo overhead attivando una funzionalità chiamata precaricamento della navigazione e poi utilizzando la risposta della rete precaricata all'interno del gestore eventi fetch
.
Workbox fornisce una libreria di assistenza che rileva se il precaricamento della navigazione è supportato e, in caso affermativo, semplifica il processo di indicazione al tuo service worker di utilizzare la risposta di rete.
Foto di Aaron Burden su Unsplash