Nel modulo precedente, alcuni concetti alla base del percorso di rendering critico erano e come le risorse di blocco della visualizzazione e di blocco dei parser possano ritardare rendering iniziale della pagina. Ora che conosci alcuni dei concetti alla base a questo punto, sarai pronto ad apprendere alcune tecniche per ottimizzare i il percorso di rendering.
Durante il caricamento di una pagina, all'interno del codice HTML viene fatto riferimento a molte risorse che forniscono una pagina con il suo aspetto e layout tramite CSS, nonché la sua interattività tramite JavaScript. In questo modulo vengono trattati una serie di concetti importanti queste risorse e il modo in cui influiscono sul tempo di caricamento di una pagina.
Blocco del rendering
Come discusso nel modulo precedente, il CSS è una risorsa di render-blocking, in quanto impedisce al browser di eseguire il rendering di qualsiasi contenuto fino a quando il modello a oggetti CSS (CSSOM). Il browser blocca il rendering per impedire la visualizzazione di Flash di Contenuti senza stile (FOUC), contenuti indesiderati dal punto di vista dell'esperienza utente.
Nel video precedente, c'è un breve FOUC in cui potete visualizzare la pagina senza con qualsiasi stile. Successivamente, tutti gli stili vengono applicati una volta che il CSS della pagina ha terminato il caricamento dalla rete e la versione senza stile della pagina immediatamente sostituita con la versione con stile.
In generale, il FOUC è qualcosa che normalmente non si vede, ma il concetto è importante capire, in modo da sapere il perché il browser blocca il rendering della pagina fino a quando il CSS non viene scaricato e applicato alla pagina. Blocco del rendering non è necessariamente indesiderato, ma vuoi ridurne al minimo la durata mantenendo il CSS ottimizzato.
Blocco del parser
Una risorsa di blocco del parser interrompe l'analizzatore sintattico HTML, ad esempio un <script>
elemento senza attributi async
o defer
. Quando il parser rileva un
<script>
, il browser deve valutare ed eseguire lo script prima
e proseguirà con l'analisi del resto del codice HTML. Ciò è dovuto alla progettazione, poiché gli script
modificare o accedere al DOM per un certo periodo di tempo mentre è ancora in fase di creazione.
<!-- This is a parser-blocking script: -->
<script src="/script.js"></script>
Quando utilizzi file JavaScript esterni (senza async
o defer
), l'analizzatore sintattico viene
bloccato dal rilevamento del file fino al suo download, analisi e
eseguito. Quando utilizzi JavaScript in linea, l'analizzatore sintattico viene bloccato in modo simile finché
lo script incorporato viene analizzato ed eseguito.
Lo scanner di precaricamento
Lo scanner di precaricamento è un'ottimizzazione del browser sotto forma di codice HTML secondario.
parser che analizza la risposta HTML non elaborata per trovare e recuperare in modo speculativo
prima che l'analizzatore sintattico HTML principale le rilevi. Per
Ad esempio, lo scanner di precaricamento consente al browser di avviare il download di un
risorsa specificata in un elemento <img>
, anche quando l'analizzatore sintattico HTML è bloccato
durante il recupero e l'elaborazione
di risorse come CSS e JavaScript.
Per poter sfruttare lo scanner di precaricamento, è necessario includere risorse critiche nel markup HTML inviato dal server. I seguenti pattern di caricamento delle risorse sono non rilevabili dallo scanner di precaricamento:
- Immagini caricate da CSS utilizzando la proprietà
background-image
. Queste immagini i riferimenti sono in CSS e non possono essere rilevati dallo scanner di precaricamento. - Script caricati dinamicamente sotto forma di markup dell'elemento
<script>
inserito nel DOM utilizzando JavaScript o i moduli caricati medianteimport()
dinamico. - HTML visualizzato sul client tramite JavaScript. Tale markup è contenuto in stringhe nelle risorse JavaScript e non è rilevabile dal precaricamento scanner.
- Dichiarazioni
@import
del CSS.
Questi pattern di caricamento delle risorse sono tutte risorse scoperte in ritardo e, di conseguenza,
non sfruttano lo scanner di precaricamento. Evitali ogni volta che è possibile. Se
evitare questi pattern non è possibile, ma potresti essere in grado di utilizzare una
Suggerimento preload
per evitare ritardi nel rilevamento delle risorse.
CSS
CSS determina la presentazione e il layout di una pagina. Come descritto in precedenza, è una risorsa che blocca la visualizzazione, quindi l'ottimizzazione del CSS potrebbe comportare impatto sul tempo di caricamento complessivo della pagina.
Minimizzazione
Minimizzando i file CSS riduce le dimensioni di una risorsa CSS, il che aumenta il download. Ciò si ottiene principalmente rimuovendo contenuti da un file CSS di origine, come spazi e altri caratteri invisibili, e la generazione il risultato in un file appena ottimizzato:
/* Unminified CSS: */
/* Heading 1 */
h1 {
font-size: 2em;
color: #000000;
}
/* Heading 2 */
h2 {
font-size: 1.5em;
color: #000000;
}
/* Minified CSS: */
h1,h2{color:#000}h1{font-size:2em}h2{font-size:1.5em}
Nella sua forma più semplice, la minimizzazione del CSS è un'ottimizzazione efficace che potrebbe migliorare il valore FCP del sito web e, in alcuni casi, anche l'LCP. Strumenti come i bundle possono eseguire automaticamente questa ottimizzazione per te in produzione le build.
Rimuovi CSS inutilizzato
Prima di eseguire il rendering dei contenuti, il browser deve scaricare e analizzare tutti fogli di stile. Il tempo necessario per completare l'analisi include anche gli stili che inutilizzati nella pagina corrente. Se utilizzi un bundler che combina tutti i CSS risorse in un unico file, è probabile che gli utenti scarichino più CSS di necessari per il rendering della pagina corrente.
Per scoprire il CSS inutilizzato per la pagina corrente, utilizza lo strumento Copertura in Chrome DevTools.
La rimozione dello spazio CSS inutilizzato ha un duplice effetto: oltre a ridurre la quantità di download tempo, stai ottimizzando la creazione dell'albero di rendering, in quanto il browser deve elaborare meno regole CSS.
Evita le dichiarazioni @import
del CSS
Anche se può sembrare pratico, dovresti evitare le dichiarazioni @import
in CSS:
/* Don't do this: */
@import url('style.css');
Analogamente al funzionamento dell'elemento <link>
in HTML, la dichiarazione @import
in CSS consente di importare una risorsa CSS esterna da un foglio di stile. La
la differenza principale tra questi due approcci è che l'elemento <link>
HTML
fa parte della risposta HTML e viene quindi scoperto molto prima rispetto a un CSS
file scaricato tramite una dichiarazione @import
.
Il motivo è che, per far sì che una dichiarazione @import
venga
rilevato, il file CSS che lo contiene deve essere prima scaricato. Questo
genera una cosiddetta catena di richieste che, nel caso dei CSS, ritarda
il tempo necessario per la visualizzazione iniziale di una pagina. Un altro svantaggio è che
i fogli di stile caricati utilizzando una dichiarazione @import
non possono essere rilevati dal
precaricano lo scanner e diventano risorse
di blocco della visualizzazione scoperte in ritardo.
<!-- Do this instead: -->
<link rel="stylesheet" href="style.css">
Nella maggior parte dei casi puoi sostituire @import
utilizzando un
Elemento <link rel="stylesheet">
. Gli elementi <link>
consentono ai fogli di stile di essere
scaricato contemporaneamente e riduce il tempo di caricamento complessivo, rispetto a @import
che scarica i fogli di stile consecutivamente.
CSS critico incorporato
Il tempo necessario per scaricare i file CSS può aumentare il valore FCP di una pagina. Incorporato
gli stili critici nel documento <head>
eliminano la richiesta di rete per un
CSS e, se eseguita correttamente, può migliorare i tempi di caricamento iniziali quando
la cache del browser dell'utente non è preparata. Il CSS rimanente può essere caricato
in modo asincrono o aggiunto alla fine dell'elemento <body>
.
<head>
<title>Page Title</title>
<!-- ... -->
<style>h1,h2{color:#000}h1{font-size:2em}h2{font-size:1.5em}</style>
</head>
<body>
<!-- Other page markup... -->
<link rel="stylesheet" href="non-critical.css">
</body>
Lo svantaggio di inserire una grande quantità di CSS comporta l'aggiunta di più byte alla Risposta HTML. Perché spesso le risorse HTML non possono essere memorizzate nella cache per molto tempo (o al tutti, ciò significa che il CSS incorporato non viene memorizzato nella cache per le pagine successive che potrebbero utilizzare lo stesso CSS nei fogli di stile esterni. Testa e misura il rendimento della tua pagina per assicurarti che i compromessi valgano l'impegno.
Demo CSS
JavaScript
JavaScript genera gran parte dell'interattività sul web, ma ha un costo. La spedizione di un codice JavaScript eccessivo può rallentare la risposta della pagina web durante la visualizzazione viene caricato e possono persino causare problemi di reattività che rallentano le interazioni. che possono essere frustranti per gli utenti.
JavaScript che blocca la visualizzazione
Quando carichi elementi <script>
senza gli attributi defer
o async
, la classe
il browser blocca l'analisi e il rendering finché lo script non viene scaricato, analizzato e
eseguito. Analogamente, gli script in linea bloccano l'analizzatore sintattico finché lo script non viene analizzato
ed eseguire il deployment.
async
contro defer
async
e defer
consentono il caricamento degli script esterni senza bloccare il codice HTML
mentre gli script (inclusi quelli incorporati) con type="module"
differita automaticamente. Tuttavia, async
e defer
presentano alcune differenze che
sono importanti da capire.
Gli script caricati con async
vengono analizzati ed eseguiti immediatamente dopo il download.
mentre gli script caricati con defer
vengono eseguiti quando è in corso l'analisi dei documenti HTML
completato. Questo si verifica contemporaneamente all'evento DOMContentLoaded
del browser.
Inoltre, async
script potrebbero essere eseguiti non nell'ordine corretto, mentre defer
script potrebbero essere eseguiti
vengono eseguite nell'ordine in cui appaiono nel markup.
Rendering lato client
In genere, dovresti evitare di usare JavaScript per eseguire il rendering di contenuti critici o di una l'elemento LCP della pagina. Questo è noto come rendering lato client ed è una tecnica ampiamente utilizzato nelle applicazioni a pagina singola (APS).
Il markup eseguito da JavaScript evita lo scanner di precaricamento, poiché le risorse contenuti nel markup visualizzato dal client non sono rilevabili dal markup. Questo potrebbe ritardare il download di risorse cruciali, come un'immagine LCP. Il browser inizia a scaricare l'immagine LCP solo dopo l'esecuzione dello script e l'aggiunta l'elemento al DOM. A sua volta, lo script può essere eseguito solo dopo rilevati, scaricati e analizzati. Questa procedura è nota come richiesta critica ed è da evitare.
Inoltre, è più probabile che il rendering di markup tramite JavaScript generi attività lunghe rispetto al markup scaricato dal server in risposta a una navigazione richiesta. L'uso intensivo del rendering lato client del codice HTML può influire negativamente latenza di interazione. Ciò è particolarmente vero nei casi in cui il DOM di una pagina molto grande, che attiva un notevole lavoro di rendering quando JavaScript modifica il DOM.
Minimizzazione
Come per i CSS, la minimizzazione di JavaScript riduce le dimensioni del file di una risorsa di script. Ciò può portare a download più rapidi, consentendo al browser di passare alla il processo di analisi e compilazione del codice JavaScript più rapidamente.
Inoltre, la minimizzazione di JavaScript va oltre la minimizzazione e altri asset, ad esempio il CSS. Quando JavaScript viene minimizzato, non viene solo rimosso. di elementi come spazi, tabulazioni e commenti, ma i simboli nella fonte JavaScript è abbreviato. Questo processo è a volte noto come uglificazione. A vedere la differenza, considera il seguente codice sorgente JavaScript:
// Unuglified JavaScript source code:
export function injectScript () {
const scriptElement = document.createElement('script');
scriptElement.src = '/js/scripts.js';
scriptElement.type = 'module';
document.body.appendChild(scriptElement);
}
Una volta uglificato il codice sorgente JavaScript precedente, il risultato potrebbe essere ad esempio il seguente snippet di codice:
// Uglified JavaScript production code:
export function injectScript(){const t=document.createElement("script");t.src="/js/scripts.js",t.type="module",document.body.appendChild(t)}
Nello snippet precedente, puoi vedere che la variabile leggibile
scriptElement
nella fonte è abbreviato in t
. Se applicato su un modello grande
raccolta di script, i risparmi possono essere notevoli, senza incidere
le funzionalità fornite da JavaScript per la produzione di un sito web.
Se utilizzi un bundler per elaborare il codice sorgente del tuo sito web, viene spesso eseguita automaticamente per le build di produzione. Gli Uglifier, come Terser, ad esempio sono altamente configurabili, che consentono di modificare aggressività dell'algoritmo di uglificazione per ottenere il massimo risparmio. Tuttavia, i valori predefiniti per qualsiasi strumento di uglificazione sono in genere sufficienti per segnalare il giusto equilibrio tra dimensioni dell'output e conservazione delle capacità.
Demo JavaScript
Verifica le tue conoscenze
Qual è il modo migliore per caricare più file CSS nel browser?
<link>
.@import
del CSS.Che cosa fa lo scanner di precaricamento del browser?
<link rel="preload">
elemento in
una risorsa HTML.
Perché il browser blocca temporaneamente l'analisi del codice HTML per impostazione predefinita quando scaricare risorse JavaScript?
A seguire: assistenza al browser con hint delle risorse
Ora che hai un quadro del modo in cui le risorse caricate nell'elemento <head>
possono
influisce sul caricamento iniziale della pagina e su varie metriche, è il momento di andare avanti. Nei prossimi
modulo, i nostri suggerimenti sulle risorse e scoprire in che modo possono fornire suggerimenti preziosi per
il browser per iniziare a caricare le risorse e aprire connessioni multiorigine
prima che il browser faccia altrimenti senza.