Prima che il browser possa eseguire il rendering della pagina, deve creare le strutture DOM e CSSOM. Di conseguenza, dobbiamo assicurarci di inviare sia il codice HTML che il codice CSS al browser il più rapidamente possibile.
Riepilogo
- Byte → caratteri → token → nodi → modello a oggetti.
- Il markup HTML viene trasformato in un DOM (Document Object Model) e il markup CSS in un CSSOM (CSS Object Model).
- DOM e CSSOM sono strutture di dati indipendenti.
- Il riquadro Prestazioni di Chrome DevTools ci consente di acquisire e controllare i costi di creazione e elaborazione di DOM e CSSOM.
Document Object Model (DOM)
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width,initial-scale=1" />
<link href="style.css" rel="stylesheet" />
<title>Critical Path</title>
</head>
<body>
<p>Hello <span>web performance</span> students!</p>
<div><img src="awesome-photo.jpg" /></div>
</body>
</html>
Iniziamo con il caso più semplice possibile: una pagina HTML semplice con un po' di testo e una singola immagine. In che modo il browser elabora questa pagina?
- Conversione: il browser legge i byte non elaborati del codice HTML dal disco o dalla rete e li converte in singoli caratteri in base alla codifica specificata del file (ad esempio, UTF-8).
- Tokenizzazione: il browser converte stringhe di caratteri in token distinti, come specificato dallo standard W3C HTML5, ad esempio "<html>", "<body>" e altre stringhe tra parentesi angolari. Ogni token ha un significato speciale e un proprio insieme di regole.
- Lexing: i token emessi vengono convertiti in "oggetti", che ne definiscono le proprietà e le regole.
- Costruzione DOM: infine, poiché il markup HTML definisce le relazioni tra i diversi tag (alcuni tag sono contenuti all'interno di altri tag), gli oggetti creati sono collegati in una struttura di dati ad albero che acquisisce anche le relazioni padre-figlio definite nel markup originale: l'oggetto HTML è un elemento padre dell'oggetto body, body è l'elemento padre dell'oggetto paragraph e così via.
L'output finale di questo intero processo è il Document Object Model (DOM) della nostra semplice pagina, che il browser utilizza per tutte le ulteriori elaborazioni della pagina.
Ogni volta che il browser elabora il markup HTML, esegue tutti i passaggi precedenti: converti i byte in caratteri, identifica i token, converti i token in nodi e crea l'albero DOM. L'intera procedura può richiedere del tempo, specialmente se abbiamo una grande quantità di codice HTML da elaborare.
Se apri Chrome DevTools e registri una sequenza temporale mentre la pagina è caricata, puoi vedere il tempo effettivo impiegato per eseguire questo passaggio. Nell'esempio riportato sopra, ci sono voluti circa 5 ms per convertire un blocco di HTML in un albero DOM. Per una pagina più grande, questo processo potrebbe richiedere molto più tempo. Durante la creazione di animazioni fluide, questo può diventare facilmente un collo di bottiglia se il browser deve elaborare grandi quantità di HTML.
L'albero DOM acquisisce le proprietà e le relazioni del markup del documento, ma non ci indica l'aspetto dell'elemento dopo il rendering. Questa è la responsabilità del CSSOM.
CSSOM (CSS Object Model)
Durante la creazione del DOM della nostra pagina semplice, il browser ha riscontrato un tag link nella sezione head del documento che fa riferimento a un foglio di stile CSS esterno: style.css
. Prevedendo di aver bisogno di questa risorsa per eseguire il rendering della pagina, invia immediatamente una richiesta per questa risorsa, che restituisce i seguenti contenuti:
body {
font-size: 16px;
}
p {
font-weight: bold;
}
span {
color: red;
}
p span {
display: none;
}
img {
float: right;
}
Avremmo potuto dichiarare i nostri stili direttamente nel markup HTML (incorporato), ma mantenere il nostro CSS indipendente dall'HTML ci consente di considerare i contenuti e il design come preoccupazioni separate: i designer possono lavorare sul CSS, gli sviluppatori possono concentrarsi sull'HTML e così via.
Come per l'HTML, dobbiamo convertire le regole CSS ricevute in un elemento comprensibile e utilizzabile dal browser. Ripetiamo quindi la procedura HTML, ma per CSS invece che per HTML:
I byte CSS vengono convertiti in caratteri, quindi token, nodi e, infine, collegati a una struttura ad albero nota come CSSOM (CSS Object Model):
Perché il CSSOM ha una struttura ad albero? Nel calcolare l'insieme finale di stili per qualsiasi oggetto della pagina, il browser inizia con la regola più generale applicabile al nodo (ad esempio, se è un elemento figlio di un elemento body, vengono applicati tutti gli stili del corpo) e poi perfeziona in modo ricorsivo gli stili calcolati applicando regole più specifiche, ovvero le regole "a cascata".
Per renderlo più concreto, prendi in considerazione la struttura CSSOM riportata sopra. Qualsiasi testo contenuto
nel tag <span>
che viene inserito nell'elemento body ha dimensioni
dei caratteri di 16 pixel e testo rosso: l'istruzione font-size
si estende
da body
a span
. Tuttavia, se un tag span
è l'elemento figlio di un tag paragrafo (p
), i suoi contenuti non vengono visualizzati.
Tieni inoltre presente che la struttura ad albero riportata sopra non è l'albero CSSOM completo e mostra solo gli stili che abbiamo deciso di sostituire nel nostro foglio di stile. Ogni browser fornisce un insieme predefinito di stili, noti anche come "stili user agent", che vengono visualizzati quando non ne forniamo di nostri. I nostri stili sostituiscono semplicemente questi valori predefiniti.
Per sapere quanto tempo richiede l'elaborazione CSS, puoi registrare una sequenza temporale in DevTools e cercare l'evento "Ricalcola stile". A differenza dell'analisi DOM, la sequenza temporale non mostra una voce "Analizza CSS" separata, ma acquisisce l'analisi e la creazione dell'albero CSSOM, oltre al calcolo ricorsivo degli stili calcolati in questo evento.
L'elaborazione del nostro semplice foglio di stile richiede circa 0,6 ms e influisce su otto elementi della pagina. Tuttavia, da dove provengono gli otto elementi? CSSOM e DOM sono strutture di dati indipendenti. Ho scoperto che il browser nasconde un passaggio importante. Ora parliamo dell'albero di rendering che collega il DOM e il CSSOM.