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

Scopri in che modo il tuo server può inviare suggerimenti al browser sulle risorse secondarie critiche.

Kenji Baheux
Kenji Baheux

Cosa sono i primi suggerimenti?

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 ai database o le CDN che accedono al server di origine) per produrre il codice HTML per la pagina richiesta. Sfortunatamente, questo "tempo di riflessione del server" genera una latenza aggiuntiva prima che il browser possa iniziare a eseguire il rendering della pagina. Di fatto, la connessione rimane inattiva per 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 avvisi iniziali: viene bloccato tutto sul server, determinando la modalità di risposta per la risorsa principale.

I primi suggerimenti sono 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 suggerimenti al browser sulle risorse secondarie critiche (ad esempio, fogli di stile per la pagina, JavaScript critico) o sulle origini che verranno probabilmente utilizzate dalla pagina mentre il server è impegnato a generare la risorsa principale. Il browser può utilizzare questi suggerimenti per il riscaldamento delle connessioni e la richiesta di sottorisorse in attesa della risorsa principale. In altre parole, i primi suggerimenti aiutano il browser a sfruttare questo "tempo di riflessione del server" svolgendo del lavoro in anticipo, accelerando così il caricamento delle pagine.

Immagine che mostra come i suggerimenti iniziali consentono alla pagina di inviare una risposta parziale.
Con suggerimenti iniziali: il server può fornire una risposta parziale con suggerimenti delle risorse mentre determina la risposta finale

In alcuni casi, il miglioramento delle prestazioni di Largest Contentful Paint può andare da diverse centinaia di millisecondi, come osservato da Shopify e da Cloudflare, e fino a un secondo più veloce, come mostrato in questo 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 principali pagine di destinazione, ovvero le pagine da cui in genere gli utenti iniziano quando visitano il tuo sito web. Potrebbe essere la home page o le pagine delle schede di prodotto più apprezzate, se hai molti utenti provenienti da altri siti web. Il motivo per cui questi punti di ingresso sono più importanti di altre pagine è perché l'utilità dei suggerimenti iniziali diminuisce man mano che l'utente naviga nel sito web (in altre parole, è più probabile che il browser disponga di tutte le sottorisorse necessarie nella seconda o terza navigazione successiva). Inoltre, è sempre una buona idea pubblicare un'ottima prima impressione.

Ora che hai questo elenco prioritario delle pagine di destinazione, il passaggio successivo consiste nell'identificare le origini o le risorse secondarie più adatte per i suggerimenti 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, ad esempio il codice JavaScript sincrono, i fogli di stile o persino i caratteri web. Allo stesso modo, cerca le origini che ospitano le sottorisorse che contribuiscono molto alle metriche utente chiave.

Tieni inoltre presente che se le tue risorse principali utilizzano già preconnect o preload, puoi considerare queste origini o risorse tra i candidati per i primi suggerimenti. Per ulteriori dettagli, consulta Come ottimizzare l'LCP. Tuttavia, copiare in modo ingenuo le istruzioni preconnect e preload dal codice HTML ai suggerimenti iniziali potrebbe non essere una soluzione ottimale.

Quando le utilizzi in HTML, in genere vuoi preconnect o preload risorse che lo Scanner di precaricamento non rileverà nel codice HTML, ad esempio caratteri o immagini di sfondo che verrebbero altrimenti rilevate in ritardo. Per i primi suggerimenti, non avrai l'HTML, quindi potresti voler eseguire preconnect su domini critici o preload risorse critiche che forse sarebbero altrimenti rilevate all'inizio dell'HTML, ad esempio il precaricamento di main.css o app.js.Inoltre, non tutti i browser supportano preload per i primi suggerimenti, vedi Supporto browser.

Il secondo passaggio consiste nel ridurre al minimo il rischio di utilizzare i suggerimenti iniziali 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 il 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 maniera specifica i suggerimenti iniziali, ma si applica a qualsiasi preload o preconnect ovunque possa essere presente. Si tratta del tipo di dettaglio più adatto all'automazione o alla creazione di modelli (ad esempio, un processo manuale ha maggiori probabilità di generare una mancata corrispondenza di hash o URL di versione 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 i suggerimenti iniziali:

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

Pochi istanti dopo, viene pubblicata la pagina web, incluso il CSS collegato. Purtroppo questa risorsa CSS viene aggiornata di frequente e la risorsa principale è già a cinque versioni avanti (abcd105) della 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 per gran parte indipendenti dal risultato della risorsa principale. Se necessario, potresti suddividere le risorse della chiave in due: una parte stabile progettata per essere utilizzata con i suggerimenti iniziali e una parte più dinamica da recuperare dopo che il browser avrà ricevuto la risorsa principale:

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

Infine, sul lato server, cerca le principali richieste di risorse inviate dai browser noti per supportare i suggerimenti iniziali e rispondi immediatamente con il modulo 103. Nella risposta 103, includi i suggerimenti di preconnessione e precaricamento pertinenti. Quando la risorsa principale è pronta, ripeti la risposta consueta (ad esempio, 200 OK in caso di esito positivo). Per la compatibilità con le versioni precedenti, è buona norma includere anche le intestazioni HTTP Link nella risposta finale, magari anche includendo 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 "dividi in due"). Ecco come:

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 103 Early Hints sia supportato in tutti i principali browser, le istruzioni che possono essere inviate tramite Early Hint variano in base al browser:

Assistenza per la preconnessione:

Supporto dei browser

  • 103
  • 103
  • 120
  • 17

Supporto precaricato:

Supporto dei browser

  • 103
  • 103
  • 123
  • x

Chrome DevTools dispone anche del supporto 103 Early Hints.

Assistenza per server

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

Attiva i suggerimenti iniziali nel modo più semplice

Se utilizzi una delle reti CDN o delle piattaforme seguenti, potrebbe non essere necessario implementare manualmente i suggerimenti iniziali. Consulta la documentazione online del provider di soluzioni per scoprire se supporta i primi suggerimenti oppure fai riferimento all'elenco non esaustivo qui:

Come evitare problemi per i clienti che non supportano i suggerimenti iniziali

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

L'invio di 103 Early Hints solo 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 sanno di attendere la risposta successiva. Inoltre, poiché i primi suggerimenti sono supportati solo per le richieste di navigazione (vedi le limitazioni attuali), offre il vantaggio aggiuntivo di evitare l'invio inutile su altre richieste.

Inoltre, consigliamo l'invio dei suggerimenti iniziali solo tramite connessioni HTTP/2 o HTTP/3.

Pattern avanzato

Se hai applicato completamente i suggerimenti iniziali alle tue pagine di destinazione chiave e ti trovi a cercare ulteriori opportunità, potrebbe essere utile il seguente pattern avanzato.

Per i visitatori che stanno nth la richiesta di pagina nell'ambito di un tipico percorso dell'utente, è possibile adattare la risposta dei suggerimenti iniziali ai contenuti più bassi e più profondi nella pagina, in altre parole utilizzando i suggerimenti iniziali per le risorse a priorità inferiore. Questo potrebbe sembrare controintuitivo dato che consigliamo di concentrarti su sottorisorse o origini ad alta priorità che bloccano la visualizzazione. 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 con priorità più bassa. Ad esempio, potresti utilizzare i suggerimenti iniziali per caricare le immagini dei prodotti o codice JS/CSS aggiuntivo necessario solo per le interazioni meno comuni degli utenti.

Limitazioni attuali

Ecco i limiti della funzionalità Early Hints implementata in Chrome:

  • Disponibile solo per le richieste di navigazione (ovvero la risorsa principale per il documento di primo livello).
  • Supporta solo preconnect e preload (ossia prefetch non è supportato).
  • Un Early Hint seguito da un reindirizzamento multiorigine nella risposta finale comporterà l'eliminazione delle risorse e delle connessioni ottenute tramite i suggerimenti iniziali.

Altri browser hanno limitazioni simili e alcuni limitano ulteriormente 103 suggerimenti in anteprima solo all'preconnect.

Passaggi successivi

A seconda dell'interesse della community, potremmo potenziare l'implementazione di Early Hints con le seguenti funzionalità:

  • Suggerimenti iniziali inviati per le richieste di risorse secondarie.
  • Suggerimenti iniziali inviati per le richieste di risorse principali iframe.
  • Supporto del precaricamento in Early Hint.

Apprezziamo il tuo input sugli aspetti a cui dare la priorità e su come migliorare ulteriormente i suggerimenti iniziali.

Relazione con H2/Push

Se conosci la funzionalità HTTP2/Push deprecata, potresti chiederti in cosa differiscono i suggerimenti iniziali. Mentre i suggerimenti iniziali richiedono un round trip per consentire al browser di iniziare a recuperare le sottorisorse critiche, con HTTP2/push il server potrebbe iniziare a eseguire il push delle sottorisorse insieme alla risposta. Sebbene tutto ciò possa sembrare incredibile, ciò ha comportato uno svantaggio strutturale fondamentale: con HTTP2/Push era estremamente difficile evitare di eseguire il push di sottorisorse che il browser già aveva. Questo effetto "eccessivo" ha comportato un utilizzo meno efficiente della larghezza di banda di rete, ostacolando significativamente i vantaggi in termini di prestazioni. Nel complesso, i dati di Chrome hanno mostrato che HTTP2/Push era di fatto un netto negativo per le prestazioni sul web.

Al contrario, i suggerimenti iniziali funzionano meglio in pratica perché combinano la capacità di inviare una risposta preliminare con suggerimenti che lasciano il browser a occuparsi del recupero o della connessione a ciò di cui ha effettivamente bisogno. Anche se Early Hints non copre tutti i casi d'uso che HTTP2/Push potrebbe affrontare in teoria, riteniamo che Early Hints sia una soluzione più pratica per velocizzare le navigazioni.

Immagine in miniatura di Pierre Bamin.