Indice dei contenuti dell'articolo:
Vuoi conoscere un segreto sulle prestazioni di Internet? I browser trascorrono una quantità eccessiva di tempo a girare i pollici in attesa di sapere cosa fare. Questa attesa influisce sulle prestazioni di caricamento della pagina. Oggi siamo lieti di illustrare cosa sono gli Early Hints, che migliora notevolmente le prestazioni di caricamento della pagina del browser e riduce il tempo di attesa.
Che cosa sono gli Early Hints?
Se traduciamo alla lettera il termine “Early Hints”, otterremo in lingua italiana “Primi suggerimenti”. Questo termine è sicuramente molto più immediato ed eloquente per comprendere meglio la funzionalità proposta già dal 2017 che vede luce verso la fine del mese di Giugno 2022.
I siti web sono diventati più sofisticati nel tempo. Pertanto, non è insolito che un server debba eseguire un lavoro non banale (ad esempio, l’accesso a database o CDN che accedono al server di origine) per produrre l’HTML per la pagina richiesta. Sfortunatamente, questo “tempo di riflessione del server” chiamato in gergo tecnico “Thinking Time”, comporta una latenza aggiuntiva prima che il browser possa iniziare a eseguire il rendering della pagina. In effetti, la connessione rimane effettivamente inattiva per tutto il tempo necessario al server per preparare la risposta.
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 suggerimenti al browser su risorse secondarie critiche (ad esempio, foglio di stile per la pagina, JavaScript critico) o origini che saranno probabilmente 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 trarre vantaggio da tale “tempo di riflessione del server” facendo un po’ di lavoro in anticipo, accelerando così il caricamento della pagina.
In alcuni casi, il miglioramento delle prestazioni per il più grande Contentful Paint può passare 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/dopo:
Il rendering della pagina non può essere completato (e l’acquirente non può ottenere la correzione del caffè e la caffetteria non può essere pagata!) finché le risorse chiave non vengono caricate. Le informazioni sulle sottorisorse necessarie al browser per caricare la pagina non sono disponibili fino a quando il server non ha atteso e restituito la risposta iniziale (il primo documento nella tabella sopra).
Nell’esempio precedente, il caricamento della pagina avrebbe potuto essere accelerato se il browser avesse saputo, prima di ricevere la risposta completa, che il foglio di stile e i quattro script successivi sarebbero stati necessari per il rendering della pagina.
Il tentativo di parallelizzare questa dipendenza è l’obiettivo di Early Hints: utilizzare in modo produttivo quel “tempo di attesa del server” per consentire al browser di eseguire passaggi critici per il rendering della pagina prima che arrivi la risposta completa del server. La barra verde “pensante” si sovrappone alla barra blu “download contenuto”, consentendo sia al browser che al server di preparare la pagina contemporaneamente. Niente più attese. Ecco di cosa tratta Early Hints!
“Gli imprenditori sanno che le prime impressioni contano. I dati di Shopify mostrano che in media, quando un negozio migliora la velocità della prima pagina nel percorso dell’acquirente del 10%, c’è un aumento del 7% delle conversioni. Vediamo grandi promesse in Early Hints essendo un altro strumento per aiutare a migliorare le prestazioni e l’esperienza per tutti i commercianti e clienti.”
— Colin Bendell , Direttore Performance Engineering di Shopify
Implementazione degli Early Hints
Early Hints è disponibile a partire dalla versione 103 di Chrome, in risposta alle richieste di navigazione o alle interazioni dell’utente che modificano l’URL nella barra di stato, con supporto sia per i suggerimenti di preconnessione che di precaricamento.
Prima di approfondire l’argomento, tieni presente che i suggerimenti iniziali non sono utili se il tuo server può inviare immediatamente un 200 (o altre risposte finali). Invece, considera l’utilizzo della risposta normale link rel=preload
o link rel=preconnect
sulla risposta principale ( Link rel HTTP header ) o nella risposta principale ( <link>
elementi), in tali situazioni. Per i casi in cui il tuo server ha bisogno di un po’ di tempo per generare la risposta principale, continua a leggere!
Detto in maniera molto diretta, al di la di tanti virtuosismi tecnici, se stai utilizzando una cache statica efficiente con un Time To First byte molto basso e veloce (inferiore ai 200ms), probabilmente gli Early Hints non offriranno nessun vantaggio tangibile se non forse nell’ordine di pochissimi millisecondi.
Il primo passo per sfruttare Early Hints consiste nell’identificare le pagine di destinazione principali, ovvero le pagine da cui i tuoi utenti in genere iniziano quando visitano il tuo sito web. Questa potrebbe essere la home page o le pagine di elenco dei prodotti popolari se hai molti utenti provenienti da altri siti Web. Il motivo per cui questi punti di ingresso contano più di altre pagine è perché l’utilità di Early Hints diminuisce man mano che l’utente naviga nel tuo sito Web (ovvero, è più probabile che il browser disponga di tutte le sottorisorse di cui ha bisogno nella seconda o terza navigazione successiva) . È sempre una buona idea anche dare un’ottima prima impressione!
Ora che hai questo elenco prioritario di pagine di destinazione, il passaggio successivo consiste nell’identificare quali origini o sottorisorse sarebbero buoni candidati per i suggerimenti di preconnessione o precaricamento , in prima approssimazione. 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 risorse secondarie che bloccano il rendering come JavaScript sincrono, fogli di stile o persino font web. Allo stesso modo, cerca le origini che ospitano sottorisorse che contribuiscono molto alle metriche utente chiave. Nota: se le tue risorse principali stanno già utilizzando <link rel=preconnect>
o<link rel=preload>
, puoi considerare queste origini o risorse tra i candidati per Early Hints. Vedi questo articolo per maggiori dettagli.
Sebbene questo rappresenti un punto di partenza decente, non è necessariamente sufficiente. Il secondo passaggio consiste nel ridurre al minimo il rischio di utilizzare Early Hints su risorse o origini che potrebbero essere obsolete o non più utilizzate dalla risorsa principale. Ad esempio, le risorse che vengono aggiornate frequentemente e con versione (ad esempio example.com/css/main.fa231e9c.css
) potrebbero non essere la scelta migliore. Nota che questa preoccupazione non è specifica per Early Hints, si applica a qualsiasi collegamento rel=preload
o rel=preconnect
ovunque potrebbero essere presenti. Questo è il tipo di dettaglio che è meglio trattare con l’automazione o la creazione di modelli (ad esempio, è più probabile che un processo manuale porti a URL hash o versione non corrispondenti tra link rel=preload
e il tag HTML effettivo che utilizza la risorsa).
A titolo di esempio, si consideri il seguente flusso:
GET /main.html
Host: example.com
User-Agent: [....] Chrome/103.0.0.0 [...]
Il server prevede che main.abcd100.css
sarà necessario e suggerisce di precaricarlo tramite Early Hints:
103 Early Hints
Link: </main.abcd100.css>; rel=preload; as=style
[...]
Pochi istanti dopo, viene servita la pagina web, incluso il CSS collegato. Sfortunatamente, questa risorsa CSS viene aggiornata frequentemente e la risorsa principale è già 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, puntare a risorse e origini abbastanza stabili e ampiamente indipendenti dal risultato per la risorsa principale. Se necessario, potresti considerare di dividere le tue risorse chiave in due: una parte stabile progettata per essere utilizzata con Early Hints e una parte più dinamica lasciata 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 principali richieste di risorse inviate dai browser noti per supportare Early Hints e rispondi immediatamente con 103 Early Hints. Nella risposta 103, includi i suggerimenti di preconnessione e precarico pertinenti. Una volta che la risorsa principale è pronta, continua con la solita risposta (ad esempio, 200 OK in caso di esito positivo). Per compatibilità con le versioni precedenti, è buona norma includere anche Link
le intestazioni HTTP nella risposta finale, magari aumentando anche con risorse critiche che sono diventate evidenti come parte della generazione della risorsa principale (ad esempio, la parte dinamica di una risorsa chiave se hai seguito la procedura “split in due” suggerimento). Ecco come sarebbe:
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 attimo 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 per Early Hints per i vari web server HTTP
Ecco un breve riepilogo del livello di supporto per Early Hints tra i più diffusi software server HTTP OSS:
- Apache: supportato tramite mod_http2.
- H2O: supportato .
- NGINX: modulo sperimentale .
- Node: non ancora supportato dal core. Disponibile come plug-in bozza per Fastify .
Va considerato necessariamente che alla base di CloudFlare c’è il Web Server NGINX (pronunciato Engine X) e pertanto considerato anche delle dinamiche aziendali e la propensione all’Open Source, che tale Patch (come successo per la patch QUIC) possa essere rilasciata anche per NGINX. Se così non fosse siamo piuttosto convinti che entro 6 o 12 mesi, tale feature sarà rilasciata dal team di sviluppo del webserver NGINX.
Abilitare gli Early Hints, nel modo più semplice
Se stai utilizzando uno dei seguenti CDN o piattaforme, potrebbe non essere necessario implementare manualmente i suggerimenti iniziali. Fare riferimento alla documentazione online del proprio fornitore di soluzioni per scoprire se supporta i suggerimenti iniziali, oppure fare riferimento all’elenco non esaustivo qui:
Early Hints su CloudFlare
Cloudflare, in quanto rete perimetrale che si trova tra client e server, è ben posizionata per fornire questi suggerimenti ai client per conto dei server. Questo è vero per alcuni motivi:
- 103 è un codice di stato sperimentale che le origini potrebbero non essere in grado di emettere da sole, principalmente per motivi legacy. Gran parte dei meccanismi che alimentano il Web presuppongono erroneamente che le richieste HTTP corrispondano sempre 1:1 con le risposte HTTP. Questa premessa errata è incorporata nella maggior parte dei software per server HTTP, rendendo difficile per i server di origine emettere le risposte Early Hints 103 prima di una risposta “finale” 200 OK.
I server perimetrali Cloudflare che gestiscono questa complessità per conto dei nostri clienti eludono ordinatamente queste sfide tecniche e fanno girare più velocemente il volano di adozione su questa nuova entusiasmante tecnologia (ne parleremo più avanti). - Il bordo di Cloudflare è molto vicino agli utenti finali . Ciò significa che possiamo fornire suggerimenti molto rapidamente, riempiendo anche i più piccoli blocchi di pensiero del server con informazioni utili che il client può utilizzare per iniziare subito a caricare le risorse.
- Cloudflare vede già il flusso di richieste e risposte dai nostri clienti. Utilizziamo questi dati per generare automaticamente suggerimenti, senza che un cliente debba apportare modifiche all’origine.
Modello avanzato
Se hai applicato completamente i suggerimenti iniziali alle tue pagine di destinazione chiave e ti trovi a cercare ulteriori opportunità, potresti essere interessato al seguente schema avanzato.
Per i visitatori che si trovano alla loro ennesima richiesta di pagina come parte di un tipico percorso dell’utente, potresti voler adattare la risposta Early Hints a contenuti che sono più bassi e più profondi nella pagina, in altre parole usando Early Hints su risorse con priorità più bassa. Questo può sembrare controintuitivo dato che abbiamo consigliato di concentrarci su risorse o origini secondarie ad alta priorità, che bloccano il rendering. Tuttavia, quando un visitatore ha navigato per un po’, è molto probabile che il suo browser abbia già tutte le risorse critiche. Da lì in poi, potrebbe avere senso spostare la tua attenzione verso risorse con priorità più bassa. Ad esempio, ciò potrebbe significare l’utilizzo di Early Hints per caricare le immagini dei prodotti o JS/CSS aggiuntivi necessari solo per interazioni utente meno comuni.
Limiti attuali degli Early Hints
Ecco le limitazioni degli Early Hints implementati in Chrome 103 e nelle versioni future fino a nuovo avviso:
- Disponibile solo per le richieste di navigazione (ovvero la risorsa principale per il documento di primo livello).
- Supporta solo preconnect e il preload (ovvero, la precarica non è supportata).
- Early Hint seguito da un reindirizzamento multiorigine sulla risposta finale comporterà l’eliminazione di Chrome delle risorse e delle connessioni ottenute tramite Early Hints.
Qual è il prossimo passo?
A seconda dell’interesse della community, si potrà aumentare la nostra implementazione di Early Hints con le seguenti capacità:
- Suggerimenti iniziali inviati su richieste di sottorisorse.
- Primi suggerimenti inviati su richieste di risorse principali iframe.
- Supporto per il prelettura nei primi suggerimenti.
Relazione con HTTP2 Push o H2/Push
Se hai familiarità con la deprecata funzione HTTP2/Push , potresti chiederti in che cosa differisce 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 inviare sottorisorse insieme alla risposta. Anche se questo suona sorprendentemente, ciò ha comportato uno svantaggio strutturale chiave: con HTTP2/Push era estremamente difficile evitare di inviare sottorisorse che il browser aveva già. Questo effetto di “spingimento eccessivo” 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 era in realtà 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 al browser il compito di recuperare o connettersi a ciò di cui ha effettivamente bisogno. Sebbene Early Hints non copra tutti i casi d’uso che HTTP2/Push potrebbe affrontare in teoria, riteniamo che Early Hints sia una soluzione più pratica per accelerare la navigazione.
Conclusione sugli Early Hints e sulle performance web
Quello che ripetiamo sempre e non stancheremo mai di ripetere è che le web performance sono un processo e non un prodotto. Pensare di abilitare gli Early Hints, implementando CloudFlare e poi non avere una cache statica come Varnish, non avere un tuning adeguato dei pool PHP-FPM, avere query lente sul Database, un’architettura hardware sottodimensionata, la mancanza di compressione brotli, la mancanza di TCP BBR con 0-RTT, non porterà a nulla se non alla convinzione di aver risolto uno delle tante decine di problemi che vanno precedentemente risolti prima di inserire Early Hints.
Non basta comprare ed indossare le scarpette da corsa di Usain Bolt per battere il record del mondo, così come non basta abilitare gli Early Hints sul Web server per avere un sito veloce.