Caricamenti delle pagine più rapidi grazie al momento di riflessione del server con i suggerimenti anticipati

Scopri come il tuo server può inviare suggerimenti al browser sulle risorse secondarie critiche.

Kenji Baheux
Kenji Baheux

Che cos'è Suggerimenti iniziali?

I siti web sono diventati più sofisticati nel tempo. Di conseguenza, non è insolito che un server debba eseguire operazioni non banali (ad esempio l'accesso a database o CDN che accedono al server di origine) per produrre il codice HTML della pagina richiesta. Purtroppo, questo "tempo di attesa del server" comporta una latenza aggiuntiva prima che il browser possa iniziare a eseguire il rendering della pagina. Infatti, la connessione rimane inattiva per tutto il tempo necessario al server per preparare la risposta.

Immagine che mostra un intervallo di tempo di elaborazione del server di 200 ms tra il caricamento della pagina e il caricamento di altre risorse.
Senza Early Hints: tutto è bloccato sul server che determina come rispondere per la risorsa principale.

Early Hints è un codice di stato HTTP (103 Early Hints) utilizzato per inviare una risposta HTTP preliminare prima di una risposta finale. In questo modo, un server può inviare al browser suggerimenti sulle risorse secondarie critiche (ad esempio gli stili della pagina, il codice JavaScript critico) o sulle origini che probabilmente verranno utilizzate dalla pagina, mentre il server è impegnato a generare la risorsa principale. Il browser può utilizzare questi suggerimenti per eseguire l'inizializzazione delle connessioni e richiedere risorse secondarie, in attesa della risorsa principale. In altre parole, gli hint in anteprima aiutano il browser a sfruttare questo "tempo di attesa del server" eseguendo alcuni compiti in anticipo, velocizzando così i caricamenti delle pagine.

Immagine che mostra in che modo gli indicatori iniziali consentono alla pagina di inviare una risposta parziale.
Con gli indizi iniziali, il server può pubblicare una risposta parziale con indizi sulle risorse mentre determina la risposta finale

In alcuni casi, il miglioramento delle prestazioni di Largest Contentful Paint può variare da alcune centinaia di millisecondi, come osservato da Shopify e Cloudflare, fino a un secondo in meno, come mostrato in questo confronto prima e dopo:

Confronto di due siti.
Confronto prima/dopo degli indicatori precoci su un sito web di test eseguito con WebPageTest (Moto G4 - DSL)

Come utilizzare gli indicatori precoci

Il primo passaggio per sfruttare gli indicatori precoci consiste nell'identificare le pagine di destinazione principali, ovvero le pagine da cui in genere iniziano gli utenti quando visitano il tuo sito web. Può trattarsi della home page o delle pagine delle schede di prodotto più apprezzate se hai molti utenti provenienti da altri siti web. Il motivo per cui questi punti di contatto sono più importanti di altre pagine è che l'utilità degli indicatori precoci diminuisce man mano che l'utente naviga nel tuo sito web (ovvero, è più probabile che il browser disponga di tutte le risorse secondarie di cui ha bisogno alla seconda o terza navigazione successiva). Inoltre, è sempre una buona idea fare una buona prima impressione.

Ora che hai questo elenco di pagine di destinazione con priorità, il passaggio successivo consiste nell'identificare le origini o le risorse secondarie che potrebbero essere buoni candidati per gli indicatori preconnect o preload. In genere, si tratta di origini e risorse secondarie che contribuiscono maggiormente alle metriche utente chiave come Largest Contentful Paint o First Contentful Paint. Più concretamente, cerca le sottorisorse che bloccano la visualizzazione, come JavaScript sincrono, fogli di stile o persino caratteri web. Allo stesso modo, cerca le origini che ospitano risorse secondarie che contribuiscono in modo significativo alle metriche utente chiave.

Tieni inoltre presente che se le tue risorse principali utilizzano già preconnect o preload, potresti prendere in considerazione queste origini o risorse tra le candidate per gli hint anticipati. Per ulteriori dettagli, leggi l'articolo su come ottimizzare l'LCP. Tuttavia, copiare in modo ingenuo le direttive preconnect e preload dall'HTML agli indicatori precoci potrebbe non essere ottimale.

Quando li utilizzi in HTML, in genere vuoi preconnect o preload risorse che lo strumento di scansione del precaricamento non rileva nell'HTML, ad esempio caratteri o immagini di sfondo che altrimenti verrebbero rilevati in ritardo. Per Early Hint non avrai il codice HTML, quindi ti conviene usare invece preconnect per i domini critici o preload risorse critiche che forse potrebbero essere scoperte all'inizio del codice HTML, ad esempio il precaricamento di main.css o app.js.Inoltre, non tutti i browser supportano preload per i Early Hints; consulta Supporto dei browser.

Il secondo passaggio consiste nel ridurre al minimo il rischio di usare Early Hints su risorse o origini che potrebbero essere obsolete o non più utilizzate dalla risorsa principale. Ad esempio, le risorse aggiornate di frequente e con versioni (ad esempio example.com/css/main.fa231e9c.css) potrebbero non essere la scelta migliore. Tieni presente che questo problema non riguarda in modo specifico i suggerimenti iniziali, ma si applica a qualsiasi preload o preconnect, ovunque siano presenti. Si tratta del tipo di dettaglio che è meglio gestire con l'automazione o i modelli (ad esempio, una procedura manuale ha maggiori probabilità di generare URL di hash o versione non corrispondenti tra preload e il tag HTML effettivo che utilizza la risorsa).

Ad esempio, considera il seguente flusso:

GET /main.html
Host: example.com
User-Agent: [....] Chrome/103.0.0.0 [...]

Il server prevede che sarà necessario main.abcd100.css e suggerisce di precaricarlo utilizzando gli indicatori anticipati:

103 Early Hints
Link: </main.abcd100.css>; rel=preload; as=style
[...]

Dopo qualche istante, la pagina web, incluso il CSS collegato, viene pubblicata. Purtroppo, questa risorsa CSS viene aggiornata di frequente e la risorsa principale è già di cinque versioni avanti (abcd105) rispetto alla risorsa CSS prevista (abcd100).

200 OK
[...]
<HTML>
<head>
   <title>Example</title>
   <link rel="stylesheet" href="/main.abcd105.css">

In generale, scegli risorse e origini abbastanza stabili e in gran parte indipendenti dal risultato della risorsa principale. Se necessario, potresti considerare la possibilità di suddividere le risorse chiave in due parti: una parte stabile progettata per essere utilizzata con i suggerimenti iniziali e una parte più dinamica da recuperare dopo che la risorsa principale è stata ricevuta dal browser:

<HTML>
<head>
   <title>Example</title>
   <link rel="stylesheet" href="/main.css">
   <link rel="stylesheet" href="/experimental.3eab3290.css">

Infine, lato server, cerca le richieste di risorse principali inviate da browser noti per supportare gli Early Hints e rispondi immediatamente con 103 Early Hints. Nella risposta 103, includi i suggerimenti di preconnessione e precaricamento pertinenti. Una volta che la risorsa principale è pronta, rispondi con la solita risposta (ad esempio 200 OK se la richiesta è andata a buon fine). Per la compatibilità con le versioni precedenti, è buona norma includere anche le intestazioni HTTP Link nella risposta finale, magari integrandole con risorse critiche che sono diventate evidenti durante la generazione della risorsa principale (ad esempio, la parte dinamica di una risorsa chiave se hai seguito il suggerimento "Dividi in due"). Ecco come sarà visualizzato:

GET /main.html
Host: example.com
User-Agent: [....] Chrome/103.0.0.0 [...]
103 Early Hints
Link: <https://fonts.google.com>; rel=preconnect
Link: </main.css>; rel=preload; as=style
Link: </common.js>; rel=preload; as=script

Pochi istanti dopo:

200 OK
Content-Length: 7531
Content-Type: text/html; charset=UTF-8
Content-encoding: br
Link: <https://fonts.google.com>; rel=preconnect
Link: </main.css>; rel=preload; as=style
Link: </common.js>; rel=preload; as=script
Link: </experimental.3eab3290.css>; rel=preload; as=style
<HTML>
<head>
   <title>Example</title>
   <link rel="stylesheet" href="/main.css">
   <link rel="stylesheet" href="/experimental.3eab3290.css">
   <script src="/common.js"></script>
   <link rel="preconnect" href="https://fonts.googleapis.com">

Supporto browser

Sebbene la funzionalità 103 Early Hint sia supportata in tutti i principali browser, le istruzioni che possono essere inviate in un Early Hint variano in base al browser:

Assistenza per il pre-collegamento:

Supporto dei browser

  • Chrome: 103.
  • Edge: 103.
  • Firefox: 120.
  • Safari: 17.

Supporto del precaricamento:

Supporto dei browser

  • Chrome: 103.
  • Edge: 103.
  • Firefox: 123.
  • Safari: non supportato.

Chrome DevTools supporta anche 103 Early Hints e le intestazioni Link sono visibili nelle risorse del documento:

Riquadro Network che mostra le intestazioni Early Hints
Le intestazioni Early Hints Link vengono mostrate in Chrome DevTools.

Tieni presente che per utilizzare le risorse Early Hints, non deve essere selezionata l'opzione Disable cache in DevTools, in quanto Early Hints utilizza la cache del browser. Per le risorse precaricate, l'iniziatore verrà visualizzato come early-hints e la dimensione come (Disk cache):

Riquadro della rete che mostra gli iniziatori degli indicatori precoci
Le risorse Early Hinted hanno un iniziatore early-hints e vengono caricate dalla cache su disco.

Inoltre, è necessario un certificato attendibile per i test HTTPS.

Firefox (a partire dalla versione 126) non dispone del supporto esplicito 103 Early Hints in DevTools, ma le risorse caricate utilizzando Early Hints non mostrano le informazioni delle intestazioni HTTP, che indicano che sono state caricate tramite Early Hints.

Assistenza per server

Ecco un breve riepilogo del livello di supporto di Early Hints tra i software dei server HTTP open source più diffusi:

Attivare gli indicatori anticipati nel modo più semplice

Se utilizzi una delle seguenti piattaforme o CDN, potresti non dover implementare manualmente gli indicatori precoci. Fai riferimento alla documentazione online del provider di soluzioni per scoprire se supporta Early Hints oppure consulta l'elenco non esaustivo qui:

Come evitare problemi per i client che non supportano gli indicatori precoci

Le risposte HTTP informative nell'intervallo 100 fanno parte dello standard HTTP, ma alcuni client o bot meno recenti potrebbero avere difficoltà con queste risposte perché, prima del lancio di 103 Early Hints, venivano utilizzate raramente per la navigazione web generale.

L'emissione di solo 103 Early Hints in risposta ai client che inviano un'intestazione di richiesta HTTP sec-fetch-mode: navigate dovrebbe garantire che questi suggerimenti vengano inviati solo per i client più recenti che sanno di dover attendere la risposta successiva. Inoltre, poiché gli indicatori in anteprima sono supportati solo per le richieste di navigazione (vedi le limitazioni attuali), questo approccio presenta il vantaggio aggiuntivo di evitare l'invio non necessario di indicatori in anteprima in altre richieste.

Inoltre, è consigliabile inviare gli indicatori precoci solo tramite connessioni HTTP/2 o HTTP/3 e la maggior parte dei browser li accetterà solo tramite questi protocolli.

Sequenza avanzata

Se hai applicato completamente i Early Hint alle tue pagine di destinazione chiave e ti ritrovi a cercare più opportunità, potrebbe interessarti il seguente pattern avanzato.

Per i visitatori che effettuano la n-esima richiesta di pagina nell'ambito di un percorso utente tipico, ti consigliamo di adattare la risposta degli indicatori precoci ai contenuti più in basso e più in profondità nella pagina, in altre parole di utilizzare gli indicatori precoci per le risorse con priorità inferiore. Questo può sembrare controintuitivo, dato che abbiamo consigliato di concentrarci su origini o sottorisorse ad alta priorità che bloccano il rendering. Tuttavia, quando un visitatore ha navigato per un po' di tempo, è molto probabile che il suo browser contenga già tutte le risorse fondamentali. Da quel momento in poi, potrebbe essere opportuno spostare l'attenzione sulle risorse a priorità inferiore. Ad esempio, potrebbe essere necessario utilizzare gli indicatori precoci per caricare le immagini dei prodotti o JS/CSS aggiuntivi necessari solo per le interazioni utente meno comuni.

Limitazioni attuali

Di seguito sono riportate le limitazioni di Early Hints come implementate in Chrome:

  • Disponibile solo per le richieste di navigazione (ovvero la risorsa principale per il documento di primo livello).
  • Supporta solo preconnect e preload (ovvero prefetch non è supportato).
  • Se gli Early Hints sono seguiti da un reindirizzamento cross-origin nella risposta finale, Chrome eliminerà le risorse e le connessioni ottenute utilizzando gli Early Hints.
  • Le risorse precaricate utilizzando Early Hints vengono memorizzate nella cache HTTP e recuperate da lì dalla pagina in un secondo momento. Pertanto, solo le risorse memorizzabili nella cache possono essere precaricate utilizzando gli indicatori in anteprima, altrimenti la risorsa verrà recuperata due volte (una volta dagli indicatori in anteprima e di nuovo dal documento). In Chrome, la cache HTTP è disattivata per i certificati HTTPS non attendibili (anche se procedi con il caricamento della pagina).
  • Il precaricamento delle immagini responsive (utilizzando imagesrcset, imagesizes o media) non è supportato utilizzando le intestazioni HTTP <link> perché l'area visibile non è definita fino alla creazione del documento. Ciò significa che non è possibile utilizzare 103 Early Hint per precaricare immagini adattabili, che potrebbero quindi caricare l'immagine errata. Segui questa discussione sulle proposte su come gestire meglio questo problema.

Altri browser presentano limitazioni simili e, come indicato in precedenza, alcuni limitano ulteriormente i 103 suggerimenti iniziali solo a preconnect.

Passaggi successivi

A seconda dell'interesse della community, potremmo migliorare la nostra implementazione degli indicatori precoci con le seguenti funzionalità:

  • Indizi precoci per le risorse non memorizzabili nella cache che utilizzano la cache della memoria anziché la cache HTTP.
  • Indizi iniziali inviati per le richieste di risorse secondarie.
  • Indizi precoci inviati per le richieste di risorse principali dell'iframe.
  • Supporto per il precaricamento in Early Hints.

Accogliamo con favore il tuo contributo su quali aspetti dare la priorità e su come migliorare ulteriormente gli Suggerimenti in anteprima.

Relazione con H2/push

Se conosci la funzionalità HTTP2/Push non più supportata, potresti chiederti in che cosa si differenziano gli indicatori precoci. Mentre Early Hints richiede un round trip affinché il browser inizi a recuperare le sottorisorse critiche, con HTTP2/push il server potrebbe iniziare a eseguire il push delle sottorisorse insieme alla risposta. Per quanto possa sembrare incredibile, ciò ha comportato uno svantaggio strutturale fondamentale: con HTTP2/Push è stato estremamente difficile evitare il push delle sottorisorse che il browser aveva già. Questo effetto di "over-pushing" ha comportato un utilizzo meno efficiente della larghezza di banda della rete, il che ha ostacolato notevolmente i vantaggi in termini di prestazioni. Nel complesso, i dati di Chrome hanno dimostrato che HTTP2/Push aveva un impatto negativo netto sul rendimento del web.

Al contrario, gli indicatori precoci hanno un rendimento migliore nella pratica perché combinano la possibilità di inviare una risposta preliminare con gli indicatori che lasciano al browser il compito di recuperare o connettersi a ciò di cui ha effettivamente bisogno. Anche se la funzionalità Early Hints non copre tutti i casi d'uso che in teoria potrebbero essere affrontati da HTTP2/Push, riteniamo che Early Hints sia una soluzione più pratica per velocizzare la navigazione.

Immagine in miniatura di Pierre Bamin.