Rendering del browser: dal testo alle immagini

Il disegno dello schermo non è magia

Quando ho iniziato a sviluppare front-end (Vue.js), ho pensato al browser semplicemente come a un “frame per la visualizzazione del codice”. Era naturale che se avessi usato

, sarebbe apparso un quadrato e se avessi usato color: red, sarebbe diventato rosso.

Tuttavia, i miei pensieri sono cambiati quando ho sperimentato nella pratica lo stuttering dell’animazione o lo scatto dello schermo durante lo scorrimento (jank). “Perché lo stesso codice funziona correttamente in Chrome ma si blocca in Internet Explorer (IE)?” “Perché la mia CPU va alle stelle quando cambio leggermente lo stile con JavaScript?”

Si scopre che il browser non è solo una cornice. Il browser era un enorme “pittore” e “architetto” che interpretava il testo (HTML/CSS) che inviavamo, calcolava matematicamente ogni pixel e lo stampava.

L’ultima volta abbiamo trasmesso i dati in tutta sicurezza attraverso strade di rete accidentate. Questa volta apriamo la casella dati (pacchetto) che è arrivata e scopriamo come il browser disegna un’immagine chiamata schermo. Questa è l’ultima storia della serie Re: Booting CS Basics.

Il browser è un cantiere in cui il codice viene letto, costruito e dipinto.

Il carico è arrivato, inizia il montaggio

Nella nostra visione del mondo da “centro logistico digitale”, il prodotto (file HTML) è ora arrivato a casa del cliente (browser). Ciò che è arrivato però non è stato un prodotto finito, ma un “manuale di montaggio”. Il gruppo di lavoro chiamato motore del browser (motore di rendering) legge questo manuale e inizia immediatamente l’assemblaggio. Questo processo è chiamato pipeline di rendering.

Passaggio 1: analisi del progetto (parsing e albero DOM)

Legge il testo HTML che arriva per primo e crea uno ‘scheletro’.

  • <html> è la radice (Root), <body> il tronco, <div> i rami…
  • Una struttura ad albero (Tree) costruita così si chiama DOM (Document Object Model). È anche l’API che permette poi a JavaScript di mettere mano a questo scheletro.

Passaggio 2: progettazione degli interni (albero CSSOM)

Quindi, leggi il file CSS e crea le “regole di stile”.

  • “Tutti i div in rosso”, “Quello con classe box misura 100px”
  • Questo si chiama CSSOM (CSS Object Model).

Passaggio 3: crea un ordine di lavoro (albero di rendering)

Ora combiniamo lo scheletro (DOM) e il design (CSSOM). Il punto importante qui è che vengono selezionate solo le “cose che appariranno effettivamente sullo schermo”.

  • E gli elementi con la proprietà display: none? Dato che non saranno visibili sullo schermo, vengono esclusi dall’albero di rendering. (Non occupano nemmeno spazio)
  • E invece visibility: hidden? Non si vede, ma occupa spazio, quindi viene incluso nell’albero di rendering.
L’albero di rendering è un elenco finale di soli “quelli che possono essere disegnati per davvero”.

[Verifica del codice] Reflow e repaint

Ora arriva il passo veramente importante. La chiave per l’ottimizzazione delle prestazioni sta qui. Una volta creato l’albero di rendering, il browser esegue due compiti pesanti.

  1. Layout / Reflow: calcola matematicamente ‘dove e con quali dimensioni’ verrà posizionato ogni elemento. (Progettazione architettonica)
  2. Paint / Repaint: nelle posizioni calcolate ‘stende davvero il colore’. (Lavori di verniciatura)

Sentiamo la differenza di costo con il codice.

const box = document.getElementById('box');

// Case 1: Codice che provoca layout (Reflow) (costoso!)
// Se cambia dimensione o posizione, vanno ricalcolati anche gli elementi vicini.
box.style.width = '200px'; 
box.style.height = '200px';
box.style.margin = '20px';

// Case 2: Codice che provoca solo paint (Repaint) (relativamente economico)
// Posizione uguale, cambia solo il colore. Niente ricalcolo, solo riverniciatura.
box.style.backgroundColor = 'blue';
box.style.color = 'white';
box.style.visibility = 'hidden';

Analisi:

  • Modifica di width: è un intervento che cambia le dimensioni dell’edificio. L’edificio accanto viene spinto via, e poi anche quello dopo. Il browser deve rifare tutti i calcoli da capo. (Si verifica un Reflow -> principale causa del calo di prestazioni)
  • Modifica di color: le dimensioni dell’edificio restano invariate, si ridipinge soltanto. Non c’è nulla da ricalcolare. (Si verifica un Repaint -> veloce)

In pratica, la maggior parte dei casi di “animazione stuttering” si verificano perché le proprietà del layout come width, left e top vengono toccate in tempo reale. In questo caso, è necessaria una tecnica per saltare il calcolo del layout utilizzando proprietà come transform.

Consigli pratici: non maltrattare il tuo browser

Non lo sapevo quando ero al college, quindi ho manipolato in modo casuale il DOM con JavaScript. Eseguendo l’istruzione for, ho modificato la dimensione e lo stile di ciascun elemento. Dal punto di vista del browser, è come essere torturati distruggendo e ricostruendo un edificio decine di volte al secondo.

Suggerimenti per garantire le prestazioni:

  1. Raggruppa le manipolazioni del DOM in un colpo solo: non cambiare gli stili uno alla volta; prepara prima una class e cambia soltanto il className, una volta sola.
  2. Le animazioni lasciale alla GPU: se al posto di left e top usi transform: translate(), la fase di layout viene saltata e se ne occupa la GPU.
  3. La differenza quando nascondi un elemento: se vuoi eliminarlo del tutto usa display: none (escluso dall’albero di rendering), se vuoi solo lasciare vuoto il suo posto usa visibility: hidden (incluso nell’albero di rendering). Tieni distinti i due casi.
Cambiare la posizione (Ridisponi) è un’operazione molto più costosa che cambiare il colore (Ridipingi).

Chiudendo la serie 1: il mio CS è stato riavviato

Con questo articolo si conclude la [Re: Booting] CS Basics Series.

Abbiamo fatto un lungo viaggio insieme.

  1. Linguaggio: il codice scritto dalle persone è stato tradotto in linguaggio macchina (build),
  2. Memoria: si è trasferito nelle stanze chiamate stack e heap,
  3. Processo (OS): ha condiviso la CPU grazie all’arte della clonazione chiamata thread,
  4. Rete: è stato spezzettato in pacchetti e ha percorso strade accidentate,
  5. Rendering: e infine, incontrando il pittore chiamato browser, è apparso davanti ai nostri occhi.

All’inizio era solo una conoscenza che memorizzavo per trovare un lavoro. Tuttavia, dopo aver riscontrato errori nella pratica e aver analizzato di nuovo, CS (ingegneria informatica) non era una lettera morta, ma un terreno solido che supportava il mio codice.

Il lavoro di fondazione è ora completo. È tempo di costruire il tuo castello su un terreno solido. Nella prossima serie [Monolith Builder], tratterò della creazione di applicazioni web utilizzando Spring Boot e Vue.js, che ho sperimentato nella pratica. Attendo con ansia il processo di trasformazione della “teoria” in “pratica”.

Lascia un commento