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'è Early Hints?

I siti web sono diventati più sofisticati nel corso del tempo. Pertanto, non è insolito che un server debba eseguire operazioni di poco conto (ad esempio, l'accesso ai database o alle reti CDN che accedono al server di origine) per produrre il codice HTML per la pagina richiesta. Purtroppo questo "tempo di riflessione del server" si traduce in una latenza aggiuntiva prima che il browser possa iniziare a visualizzare la pagina. In effetti, la connessione rimane inattiva per tutto il tempo necessario al server per preparare la risposta.

Immagine che mostra un intervallo di tempo di 200 ms tra il caricamento della pagina e il caricamento di altre risorse del server.
Senza Early Hints: tutto è bloccato sul server che determina la modalità di risposta 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. Ciò consente a un server di inviare al browser suggerimenti sulle risorse secondarie critiche (ad esempio, fogli di stile per la pagina, 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 riscaldare le connessioni e richiedere risorse secondarie, in attesa della risorsa principale. In altre parole, Early Hints aiuta il browser a sfruttare il "tempo di riflessione del server" svolgendo alcune attività in anticipo, velocizzando così il caricamento delle pagine.

Immagine che mostra in che modo Early Hints consente alla pagina di inviare una risposta parziale.
Con Early Hints: il server può fornire una risposta parziale con hint delle risorse mentre determina la risposta finale

In alcuni casi, il miglioramento delle prestazioni dell'applicazione Largest Contentful Paint può passare da diverse centinaia di millisecondi, come osservato da Shopify e da Cloudflare, fino a un secondo più rapidamente, come si vede nel confronto prima e dopo:

Confronto tra due siti.
Confronto prima/dopo dei suggerimenti iniziali su un sito web di test eseguito con WebPageTest (Moto G4 - DSL)

Come utilizzare i suggerimenti iniziali

Il primo passaggio per sfruttare i suggerimenti iniziali consiste nell'identificare le pagine di destinazione principali, ovvero le pagine da cui gli utenti iniziano generalmente quando visitano il tuo sito web. Potrebbe trattarsi della home page o delle pagine con schede di prodotto più apprezzate se molti utenti provengono da altri siti web. Il motivo per cui questi punti di ingresso sono più importanti delle altre pagine è che l'utilità dei suggerimenti iniziali diminuisce quando l'utente naviga nel sito web (in altre parole, è più probabile che il browser disponga di tutte le sottorisorse di cui ha bisogno durante la seconda o terza navigazione successiva). È sempre bene fare un'ottima prima impressione.

Ora che hai questo elenco prioritario di pagine di destinazione, il passaggio successivo consiste nell'identificare le origini o le sottorisorse idonee per i suggerimenti preconnect o preload. In genere si tratta delle origini e delle sottorisorse 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 considerare queste origini o risorse tra i candidati per i Early Hints. Per ulteriori dettagli, leggi l'articolo su come ottimizzare l'LCP. Tuttavia, copiare in modo ingenuo le istruzioni preconnect e preload dal codice HTML ai suggerimenti iniziali potrebbe non essere ottimale.

Quando li utilizzi in HTML, in genere conviene preconnect o preload risorse che lo Scanner di precaricamento non rileva nel codice HTML, ad esempio caratteri o immagini di sfondo che altrimenti rientrerebbero 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 che vengono aggiornate di frequente e sottoposte al controllo delle 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 più adatto all'automazione o ai modelli (ad esempio, un processo manuale ha maggiori probabilità di generare hash o URL di versione non corrispondenti tra preload e l'effettivo tag HTML che utilizza la risorsa).

Considera ad esempio il flusso seguente:

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 Early Hints:

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

Poco dopo, viene pubblicata la pagina web, con il CSS collegato. Purtroppo questa risorsa CSS viene aggiornata di frequente e la risorsa principale si trova 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, punta a risorse e origini abbastanza stabili e in gran parte indipendenti dall'esito 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, sul lato server, cerca le richieste di risorse principali inviate dai browser che supportano Early Hints e rispondi immediatamente con 103 Early Hints. Nella risposta 103, includi i hint pertinenti di preconnessione e precaricamento. Quando la risorsa principale è pronta, ripeti la risposta abituale (ad esempio, 200 OK in caso di esito positivo). Per garantire la compatibilità con le versioni precedenti, è buona norma includere anche le intestazioni HTTP Link nella risposta finale, magari anche aumentandone le 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 di suddivisione in due). Ecco come si presenta:

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

Qualche istante 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 del 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 la preconnessione:

Supporto dei browser

  • 103
  • 103
  • 120
  • 17

Supporto del precaricamento:

Supporto dei browser

  • 103
  • 103
  • 123
  • x

Chrome DevTools dispone inoltre del supporto 103 Early Hints e le intestazioni Link sono visibili nelle risorse dei documenti:

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

Tieni presente che puoi usare le risorse Early Hints: Disable cache non deve essere selezionato in DevTools perché utilizza la cache del browser. Per le risorse precaricate, l'iniziatore verrà visualizzato come early-hints e la dimensione come (Disk cache):

Riquadro Rete che mostra gli iniziatori dei Early Hints
Le risorse Early Hinted hanno un iniziatore early-hints e vengono caricate dalla cache su disco.

Richiede anche 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 per Early Hints tra i più diffusi software open source per server HTTP:

Abilita Early Hints nel modo più semplice

Se utilizzi una delle seguenti reti CDN o piattaforme, potrebbe non essere necessario implementare manualmente i suggerimenti iniziali. 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 Early Hints

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

L'emissione solo di 103 Early Hint in risposta ai client che inviano un'intestazione della richiesta HTTP sec-fetch-mode: navigate dovrebbe garantire che questi hint vengano inviati solo per i client più recenti che comprendono di attendere la risposta successiva. Inoltre, poiché i primi suggerimenti sono supportati solo per le richieste di navigazione (vedi le limitazioni attuali), questo ha l'ulteriore vantaggio di evitare l'invio inutile per altre richieste.

Inoltre, si consiglia di inviare i primi suggerimenti 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 si trovano nella richiesta di pagina nth nell'ambito di un tipico percorso dell'utente, potresti voler adattare la risposta Early Hint ai contenuti sempre più in basso nella pagina, in altre parole utilizzando la funzionalità Early Hints per le risorse con priorità più bassa. 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 questo momento in poi, potrebbe essere opportuno concentrare l'attenzione sulle risorse a priorità più bassa. Ad esempio, ciò potrebbe significare utilizzare Early Hints per caricare le immagini dei prodotti o CSS/JS aggiuntivi necessari solo per interazioni meno comuni degli utenti.

Limitazioni attuali

Di seguito sono riportate le limitazioni dei suggerimenti iniziali implementati 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).
  • I Early Hint seguiti da un reindirizzamento multiorigine alla risposta finale comporteranno l'eliminazione delle risorse e delle connessioni ottenute da Early Hint in Chrome.
  • Le risorse precaricate utilizzando Early Hints vengono memorizzate nella cache HTTP e recuperate da lì dalla pagina in un secondo momento. Di conseguenza, solo le risorse memorizzabili nella cache possono essere precaricate utilizzando Early Hints o la risorsa verrà recuperata due volte (una volta dai Early Hint e di nuovo dal documento). In Chrome, la cache HTTP è disattivata per i certificati HTTPS non attendibili (anche se continui a caricare la pagina).

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

Passaggi successivi

A seconda dell'interesse della community, potremmo aumentare l'implementazione dei suggerimenti iniziali con le seguenti funzionalità:

  • Early Hints per risorse non memorizzabili nella cache utilizzando la cache di memoria anziché la cache HTTP.
  • Early Hints inviati nelle richieste di sottorisorse.
  • Early Hints inviati nelle richieste di risorse principali iframe.
  • Supporto del precaricamento nei Early Hints.

Apprezziamo il tuo feedback sugli aspetti a cui dare la priorità e su come migliorare ulteriormente la funzionalità Early Hint.

Relazione con H2/push

Se conosci la funzionalità HTTP2/Push deprecata, potresti chiederti le differenze con Early Hints. 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, questo ha portato a uno svantaggio strutturale fondamentale: con HTTP2/Push è stato estremamente difficile evitare il push delle sottorisorse che il browser aveva già. Questo effetto "over-push" ha comportato un utilizzo meno efficiente della larghezza di banda della rete, che ha ostacolato in modo significativo i vantaggi in termini di prestazioni. Nel complesso, i dati di Chrome hanno mostrato che HTTP2/Push è stato di fatto un netto negativo per le prestazioni sul web.

Al contrario, Early Hints funziona meglio nella pratica perché combina la capacità di inviare una risposta preliminare con suggerimenti che lasciano il browser responsabile 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.