Le dimensioni DOM di grandi dimensioni hanno un impatto maggiore sull'interattività di quanto si possa pensare. Questa guida spiega perché e cosa puoi fare.
Non c'è modo di evitarlo: quando crei una pagina web, questa avrà un DOM (Document Object Model). Il DOM rappresenta la struttura del codice HTML della pagina e consente a JavaScript e CSS di accedere alla struttura e ai contenuti della pagina.
Il problema, tuttavia, è che le dimensioni del DOM incidono sulla capacità di un browser di visualizzare una pagina in modo rapido ed efficiente. In generale, più un DOM è grande, più costoso sarà inizialmente eseguire il rendering della pagina e aggiornarne il rendering in un secondo momento nel ciclo di vita della pagina.
Questo diventa problematico nelle pagine con DOM di grandi dimensioni quando le interazioni che modificano o aggiornano il DOM attivano costose operazioni di layout che incidono sulla capacità della pagina di rispondere rapidamente. Un lavoro di layout costoso può influire sull'Interaction to Next Paint (INP) di una pagina. Se vuoi che una pagina risponda rapidamente alle interazioni degli utenti, devi assicurarti che le dimensioni del DOM siano grandi quanto necessario.
Quando il DOM di una pagina è troppo grande?
Secondo Lighthouse, le dimensioni del DOM di una pagina sono eccessive quando superano i 1400 nodi. Lighthouse inizierà a generare avvisi quando il DOM di una pagina supera gli 800 nodi. Prendiamo come esempio il seguente codice HTML:
<ul>
<li>List item one.</li>
<li>List item two.</li>
<li>List item three.</li>
</ul>
Nel codice riportato sopra, ci sono quattro elementi DOM: l'elemento <ul>
e i suoi tre elementi secondari <li>
. La pagina web avrà quasi certamente molti più nodi rispetto a questo, quindi è importante capire cosa è possibile fare per tenere sotto controllo le dimensioni del DOM, oltre ad altre strategie per ottimizzare il lavoro di rendering una volta ridotto il più possibile il DOM di una pagina.
In che modo i DOM di grandi dimensioni influiscono sulle prestazioni delle pagine?
I DOM di grandi dimensioni influiscono sulle prestazioni delle pagine in diversi modi:
- Durante il rendering iniziale della pagina. Quando il CSS viene applicato a una pagina, viene creata una struttura simile al DOM, nota come CSS Object Model (CSSOM). Man mano che i selettori CSS diventano più specifici, il CSSOM diventa più complesso e occorre più tempo per eseguire le operazioni necessarie di layout, stile, compositing e disegno per disegnare la pagina web sullo schermo. Questo lavoro aggiuntivo aumenta la latenza di interazione per le interazioni che si verificano nelle prime fasi del caricamento della pagina.
- Quando le interazioni modificano il DOM tramite l'inserimento o l'eliminazione di elementi o tramite la modifica dei contenuti e degli stili del DOM, il lavoro necessario per eseguire il rendering dell'aggiornamento può comportare costosi lavori di layout, stile, compositing e colorazione. Come nel caso della visualizzazione iniziale della pagina, un aumento della specificità del selettore CSS può contribuire al lavoro di rendering quando gli elementi HTML vengono inseriti nel DOM come risultato di un'interazione.
- Quando JavaScript interroga il DOM, i riferimenti agli elementi DOM vengono archiviati in memoria. Ad esempio, se chiami
document.querySelectorAll
per selezionare tutti gli elementi<div>
di una pagina, il costo della memoria potrebbe essere considerevole se il risultato restituisce un numero elevato di elementi DOM.
Tutti questi fattori possono influenzare l'interattività, ma il secondo elemento dell'elenco precedente è di particolare importanza. Se un'interazione comporta una modifica del DOM, può comportare molto lavoro che può contribuire a un INP scadente su una pagina.
Come posso misurare le dimensioni del DOM?
Puoi misurare le dimensioni del DOM in due modi. Il primo metodo utilizza Lighthouse. Quando esegui un controllo, le statistiche del DOM della pagina corrente saranno nella sezione "Evita dimensioni DOM eccessive " sotto l'intestazione "Diagnostica". In questa sezione puoi vedere il numero totale di elementi DOM, l'elemento DOM che contiene il maggior numero di elementi secondari e l'elemento DOM più profondo.
Un metodo più semplice prevede l'utilizzo della console JavaScript negli strumenti per sviluppatori dei principali browser. Per ottenere il numero totale di elementi HTML nel DOM, puoi utilizzare il seguente codice nella console dopo il caricamento della pagina:
document.querySelectorAll('*').length;
Se vuoi visualizzare l'aggiornamento delle dimensioni del DOM in tempo reale, puoi utilizzare anche lo strumento di monitoraggio delle prestazioni. Con questo strumento, puoi correlare le operazioni di layout e stile (e altri aspetti del rendimento) insieme alle dimensioni del DOM correnti.
Se le dimensioni del DOM si avvicinano alla soglia di avviso del DOM Lighthouse (o non riescono del tutto), il passaggio successivo consiste nel capire come ridurre le dimensioni del DOM al fine di migliorare la capacità della pagina di rispondere alle interazioni degli utenti in modo da migliorare l'INP del sito web.
Come faccio a misurare il numero di elementi DOM interessati da un'interazione?
Se stai profilando un'interazione lenta nel lab che sospetti possa avere a che fare con le dimensioni del DOM della pagina, puoi capire quanti elementi DOM sono stati interessati selezionando qualsiasi attività nel profiler con l'etichetta "Ricalcola stile" e osservare i dati contestuali nel riquadro inferiore.
Nello screenshot riportato sopra, osserva che il ricalcolo dello stile dell'opera, se selezionato, mostra il numero di elementi interessati. Mentre lo screenshot riportato sopra mostra un caso estremo dell'effetto delle dimensioni del DOM sul rendering del lavoro in una pagina con molti elementi DOM, queste informazioni diagnostiche sono utili in ogni caso per determinare se le dimensioni del DOM rappresentano un fattore limitante relativo al tempo necessario per la visualizzazione del frame successivo in risposta a un'interazione.
Come faccio a ridurre le dimensioni del DOM?
Oltre a verificare l'eventuale presenza di markup non necessario nel codice HTML del sito web, il modo principale per ridurre le dimensioni del DOM è ridurre la profondità del DOM. Un segnale che il DOM potrebbe essere inutilmente dettagliato è se noti un markup simile al seguente nella scheda Elementi degli strumenti per sviluppatori del tuo browser:
<div>
<div>
<div>
<div>
<!-- Contents -->
</div>
</div>
</div>
</div>
Se noti pattern come questo, probabilmente puoi semplificarli appiattisce la struttura DOM. In questo modo ridurrai il numero di elementi DOM e probabilmente avrai l'opportunità di semplificare gli stili di pagina.
La profondità DOM può anche essere un sintomo dei framework utilizzati. In particolare, i framework basati su componenti, come quelli che si basano su JSX, richiedono di nidificare più componenti in un container principale.
Tuttavia, molti framework consentono di evitare la nidificazione dei componenti grazie all'uso di quelli che sono noti come frammenti. I framework basati su componenti che offrono frammenti come funzionalità includono (a titolo esemplificativo) quanto segue:
L'uso dei frammenti nel framework preferito consente di ridurre la profondità del DOM. Se ti preoccupa l'impatto della suddivisione della struttura del DOM sullo stile, potresti trarre vantaggio dall'utilizzo di modalità di layout più moderne (e più veloci), come flexbox o grid.
Altre strategie da considerare
Anche se ti devi preoccupare di appiattire l'albero DOM e rimuovere gli elementi HTML non necessari per mantenere il DOM il più piccolo possibile, il DOM può comunque essere molto grande e comportare molto lavoro di rendering poiché cambia in risposta alle interazioni degli utenti. Se ti trovi in questa posizione, puoi prendere in considerazione altre strategie per limitare il lavoro di rendering.
Prendi in considerazione un approccio additivo
Potresti trovarti in una posizione in cui grandi parti della tua pagina non sono inizialmente visibili all'utente quando viene visualizzata per la prima volta. Potrebbe trattarsi di un'opportunità per eseguire il caricamento lento del codice HTML omettendo queste parti del DOM all'avvio, ma aggiungendole quando l'utente interagisce con le parti della pagina che richiedono gli aspetti inizialmente nascosti della pagina.
Questo approccio è utile sia durante il caricamento iniziale che anche dopo. Per il caricamento iniziale della pagina, devi svolgere un lavoro di rendering inferiore, il che significa che il tuo payload HTML iniziale sarà più leggero e il rendering sarà più rapido. Questo darà alle interazioni durante quel periodo cruciale più opportunità di svolgersi con meno concorrenza per attirare l'attenzione del thread principale.
Se molte parti della pagina sono inizialmente nascoste al caricamento, potrebbe anche velocizzare le altre interazioni che attivano il rendering. Tuttavia, man mano che altre interazioni aggiungono altro al DOM, il lavoro di rendering aumenterà man mano che il DOM cresce durante il ciclo di vita della pagina.
L'aggiunta al DOM nel tempo può essere difficile e ha i suoi compromessi. Se scegli questa strada, è probabile che tu stia effettuando richieste di rete per ottenere i dati da compilare nel codice HTML che intendi aggiungere alla pagina in risposta a un'interazione di un utente. Sebbene le richieste di rete in corso non vengano conteggiate ai fini dell'INP, potrebbero aumentare la latenza percepita. Se possibile, mostra una rotellina di caricamento o un altro indicatore che indica che i dati sono in fase di recupero, in modo che gli utenti capiscano che sta succedendo qualcosa.
Limita la complessità del selettore CSS
Quando il browser analizza i selettori nel CSS, deve attraversare l'albero DOM per capire come e se questi selettori si applicano al layout corrente. Più sono complessi questi selettori, maggiore è il lavoro che il browser deve svolgere per eseguire sia il rendering iniziale della pagina sia i ricalcoli di stile e il lavoro di layout più necessari se la pagina cambia a seguito di un'interazione.
Utilizza la proprietà content-visibility
CSS offre la proprietà content-visibility
, che rappresenta a tutti gli effetti un modo per eseguire il rendering lento degli elementi DOM fuori schermo. Man mano che gli elementi si avvicinano all'area visibile, vengono visualizzati on demand. I vantaggi di content-visibility
non riducono solo una notevole quantità di lavoro nel rendering della pagina iniziale, ma saltano anche il lavoro di rendering per gli elementi fuori schermo quando il DOM della pagina viene modificato a seguito di un'interazione dell'utente.
Conclusione
Ridurre le dimensioni del DOM solo a quanto strettamente necessario è un buon modo per ottimizzare l'INP del sito web. In questo modo, puoi ridurre il tempo necessario al browser per eseguire le operazioni di layout e rendering quando il DOM viene aggiornato. Anche se non riesci a ridurre in modo significativo le dimensioni del DOM, puoi utilizzare alcune tecniche per isolare il lavoro di rendering a un sottoalbero del DOM, come il contenimento CSS e la proprietà CSS content-visibility
.
A prescindere da ciò che intendi fare, creando un ambiente in cui il lavoro di rendering è ridotto al minimo e riducendo la quantità di lavoro di rendering della tua pagina in risposta alle interazioni, il risultato sarà che il tuo sito web si sentirà più reattivo per gli utenti quando interagiscono con essi. Ciò significa che il tuo sito web avrà un INP inferiore, il che si traduce in un'esperienza utente migliore.
Immagine hero di Unsplash, di Louis Reed.