Migliorare Largest Contentful Paint nell'ecosistema JavaScript.
Nell'ambito del progetto Aurora, Google sta collaborando con i più diffusi framework web per garantirne le buone prestazioni secondo i Core Web Vitals. Angular e Next.js hanno già inserito il carattere incorporato, come spiegato nella prima parte di questo articolo. La seconda ottimizzazione che tratteremo è l'incorporamento di CSS critico, che ora è abilitato per impostazione predefinita nell'interfaccia a riga di comando di Angular e ha un'implementazione in corso in Nuxt.js.
Caratteri incorporati
Dopo aver analizzato centinaia di applicazioni, il team di Aurora ha scoperto che gli sviluppatori spesso includono caratteri
nelle applicazioni facendoli riferimento nell'elemento <head>
di index.html
. Ecco un esempio di come apparirà una volta includendo le icone Material:
<!doctype html>
<html lang="en">
<head>
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
...
</html>
Anche se questo pattern è completamente valido e funzionale, blocca il rendering dell'applicazione e introduce una richiesta aggiuntiva. Per comprendere meglio il problema, osserva il codice sorgente del foglio di stile indicato nel precedente codice HTML:
/* fallback */
@font-face {
font-family: 'Material Icons';
font-style: normal;
font-weight: 400;
src: url(https://fonts.gstatic.com/font.woff2) format('woff2');
}
.material-icons {
/*...*/
}
Osserva come la definizione di font-face
fa riferimento a un file esterno ospitato su fonts.gstatic.com
.
Durante il caricamento dell'applicazione, il browser deve prima scaricare il foglio di stile originale indicato nell'intestazione.
Successivamente, il browser scarica il file woff2
e, infine, può procedere con il rendering
dell'applicazione.
Un'opportunità per l'ottimizzazione consiste nel scaricare il foglio di stile iniziale al momento della creazione e incorporarlo in
index.html
. In questo modo viene saltato un intero round trip alla CDN in fase di runtime, riducendo il tempo di blocco.
Durante la creazione dell'applicazione, viene inviata una richiesta alla rete CDN che recupera il foglio di stile e lo inserisce nel file HTML, aggiungendo un <link rel=preconnect>
al dominio. Applicando questa tecnica, otterremmo il seguente risultato:
<!doctype html>
<html lang="en">
<head>
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin >
<style type="text/css">
@font-face{font-family:'Material Icons';font-style:normal;font-weight:400;src:url(https://fonts.gstatic.com/font.woff2) format('woff2');}.material-icons{/*...*/}</style>
...
</html>
I caratteri incorporati sono ora disponibili in Next.js e Angular
Quando gli sviluppatori di framework implementano l'ottimizzazione negli strumenti sottostanti, semplificano l'abilitazione delle applicazioni nuove e esistenti, portando il miglioramento all'intero ecosistema.
Questo miglioramento è attivato per impostazione predefinita da Next.js v10.2 e Angular v11. Entrambi supportano l'incorporamento dei caratteri Google e Adobe. Angular prevede di introdurre quest'ultimo nella versione 12.2.
Puoi trovare l'implementazione del font inlining in Next.js su GitHub e guardare il video che spiega questa ottimizzazione nel contesto di Angular.
Incorporazione di CSS fondamentale
Un altro miglioramento comporta il miglioramento delle metriche First Contentful Paint (FCP) e Largest Contentful Paint (LCP) tramite l'incorporamento di un CSS fondamentale. Il CSS fondamentale di una pagina include tutti gli stili usati nella visualizzazione iniziale. Per scoprire di più sull'argomento, consulta Rimandare i CSS non critici.
Abbiamo notato che molte applicazioni caricano gli stili in modo sincrono, il che blocca il rendering delle applicazioni. Una soluzione rapida consiste nel caricare gli stili in modo asincrono. Anziché caricare gli script con media="all"
, imposta il valore dell'attributo media
su print
e, una volta completato il caricamento, sostituisci il valore dell'attributo con all
:
<link rel="stylesheet" href="..." media="print" onload="this.media='all'">
Questa pratica, tuttavia, può causare uno sfarfallio dei contenuti senza stile.
Il video riportato sopra mostra il rendering di una pagina, che carica i suoi stili in modo asincrono. Lo sfarfallio si verifica perché il browser inizia a scaricare gli stili, quindi esegue il rendering del codice HTML che segue. Una volta che il browser scarica gli stili, attiva l'evento onload
dell'elemento link,
aggiornando l'attributo media
in all
e applica gli stili al DOM.
Nell'intervallo di tempo che intercorre tra il rendering del codice HTML e l'applicazione degli stili, la pagina risulta parzialmente priva di stile. Quando il browser utilizza gli stili, notiamo uno sfarfallio, che rappresenta un'esperienza utente negativa e genera regressioni in Cumulative Layout Shift (CLS).
L'incorporamento fondamentale di CSS, insieme al caricamento in stile asincrono, possono migliorare il comportamento di caricamento. Lo strumento critters individua gli stili utilizzati nella pagina osservando i selettori in un foglio di stile e confrontandoli con il codice HTML. Quando trova una corrispondenza, considera gli stili corrispondenti come parte del CSS fondamentale e li incorpora.
Ad esempio:
<head> <link rel="stylesheet" href="/styles.css" media="print" onload="this.media='all'"> </head> <body> <section> <button class="primary"></button> </section> </body>
/* styles.css */ section button.primary { /* ... */ } .list { /* ... */ }
Nell'esempio precedente, le bestioline leggono e analizzano i contenuti di styles.css
. Dopodiché, associa i due selettori al codice HTML e scopre che utilizziamo section button.primary
.
Infine, le bestioline incorporano gli stili corrispondenti nell'elemento <head>
della pagina, ottenendo come risultato:
<head> <link rel="stylesheet" href="/styles.css" media="print" onload="this.media='all'"> <style> section button.primary { /* ... */ } </style> </head> <body> <section> <button class="primary"></button> </section> </body>
Dopo aver incorporato il codice CSS fondamentale nell'HTML, noterai che lo sfarfallio della pagina è scomparso:
L'incorporamento critico di CSS è ora disponibile in Angular e attivato per impostazione predefinita nella versione 12. Se stai utilizzando la versione 11,
attivala impostando la proprietà inlineCritical
su true
in angular.json
. Per attivare questa funzionalità in Next.js, aggiungi experimental: { optimizeCss: true }
a next.config.js
.
Conclusioni
In questo post abbiamo parlato di alcune delle collaborazioni tra Chrome e framework web. Se sei un autore di framework e riconosci alcuni dei problemi che abbiamo affrontato nella tua tecnologia, speriamo che le nostre scoperte ti ispirano ad applicare ottimizzazioni del rendimento simili.
Scopri di più sui miglioramenti. Puoi trovare un elenco completo del lavoro di ottimizzazione che abbiamo svolto per i Segnali web essenziali nel post Ti presentiamo Aurora.