Le dimensioni elevate del DOM influiscono sull'interattività più di quanto si pensi. Questa guida spiega il motivo e cosa puoi fare.
Non c'è modo di aggirarlo: quando crei una pagina web, questa avrà un Document Object Model (DOM). Il DOM rappresenta la struttura dell'HTML della pagina e consente a JavaScript e CSS di accedere alla struttura e ai contenuti di una pagina.
Il problema, però, è che le dimensioni del DOM influiscono sulla capacità di un browser di eseguire il rendering di una pagina in modo rapido ed efficiente. In generale, più grande è un DOM, più costoso è il rendering iniziale della pagina e il relativo aggiornamento in un secondo momento nel ciclo di vita della pagina.
Questo diventa problematico nelle pagine con DOM molto grandi quando le interazioni che modificano o aggiornano il DOM attivano operazioni di layout costose che influiscono sulla capacità della pagina di rispondere rapidamente. Lavori di layout costosi possono influire sull'Interaction to Next Paint (INP) di una pagina. Se vuoi che una pagina risponda rapidamente alle interazioni degli utenti, è importante assicurarti che le dimensioni del DOM siano solo quelle necessarie.
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 lanciare avvisi quando il DOM di una pagina supera gli 800 nodi. Prendi ad 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 sono presenti quattro elementi DOM: l'elemento <ul>
e i suoi tre elementi secondari <li>
. La tua pagina web avrà quasi certamente molti più nodi, quindi è importante capire cosa puoi fare per tenere sotto controllo le dimensioni del DOM, nonché altre strategie per ottimizzare il lavoro di rendering dopo aver ridotto il DOM di una pagina al minimo possibile.
In che modo gli alberi DOM di grandi dimensioni influiscono sul rendimento della pagina?
I DOM di grandi dimensioni influiscono sul rendimento della pagina 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 di layout, stile, composizione e pittura necessarie per disegnare la pagina web sullo schermo. Questo lavoro aggiuntivo aumenta la latenza di interazione per le interazioni che si verificano all'inizio del caricamento della pagina.
- Quando le interazioni modificano il DOM, tramite l'inserimento o l'eliminazione di elementi o modificando i contenuti e gli stili del DOM, il lavoro necessario per eseguire il rendering dell'aggiornamento può comportare un costo molto elevato per il layout, lo stile, la composizione e la pittura. Come nel caso del rendering iniziale della pagina, un aumento della specificità del selettore CSS può aumentare il lavoro di rendering quando gli elementi HTML vengono inseriti nel DOM a seguito di un'interazione.
- Quando JavaScript esegue query sul DOM, i riferimenti agli elementi DOM vengono memorizzati nella memoria. Ad esempio, se chiami
document.querySelectorAll
per selezionare tutti gli elementi<div>
in una pagina, il costo della memoria potrebbe essere considerevole se il risultato restituisce un numero elevato di elementi DOM.
Tutti questi fattori possono influire sull'interattività, ma il secondo elemento dell'elenco riportato sopra è di particolare importanza. Se un'interazione comporta una modifica al DOM, può avviare un sacco di lavoro che può contribuire a un INP scadente in una pagina.
Come faccio a 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 sul DOM della pagina corrente saranno disponibili nel controllo "Evita di usare un DOM di dimensioni eccessive" nella sezione "Diagnostica". In questa sezione puoi vedere il numero totale di elementi DOM, l'elemento DOM contenente 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 di qualsiasi browser principale. 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 anche utilizzare lo strumento di monitoraggio del rendimento. Con questo strumento puoi correlare le operazioni di layout e stile (e altri aspetti del rendimento) alle dimensioni attuali del DOM.
Se le dimensioni del DOM si stanno avvicinando alla soglia di avviso delle dimensioni del DOM di Lighthouse o non vanno a buon fine, il passaggio successivo consiste nel capire come ridurre le dimensioni del DOM per migliorare la capacità della pagina di rispondere alle interazioni degli utenti in modo da migliorare l'INP del tuo sito web.
Come faccio a misurare il numero di elementi DOM interessati da un'interazione?
Se nel laboratorio stai creando il profilo di un'interazione lenta 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 etichettata come "Ricalcolo stile" e osservando i dati contestuali nel riquadro in basso.
Nello screenshot sopra, osserva che il ricalcolo dello stile dell'opera, se selezionato, mostra il numero di elementi interessati. Sebbene lo screenshot sopra riportato mostri un caso estremo dell'effetto delle dimensioni del DOM sul lavoro di rendering in una pagina con molti elementi DOM, queste informazioni di diagnostica sono utili in ogni caso per determinare se le dimensioni del DOM sono un fattore limitante nel tempo necessario per la visualizzazione del frame successivo in risposta a un'interazione.
Come faccio a ridurre le dimensioni del DOM?
Oltre a controllare il codice HTML del tuo sito web per rilevare markup non necessario, il modo principale per ridurre le dimensioni del DOM è ridurre la profondità del DOM. Un indicatore che il DOM potrebbe essere inutilmente complesso è la visualizzazione di un markup simile a questo nella scheda Elementi degli strumenti per sviluppatori del browser:
<div>
<div>
<div>
<div>
<!-- Contents -->
</div>
</div>
</div>
</div>
Quando noti pattern come questo, probabilmente puoi semplificarli appiattando la struttura DOM. In questo modo ridurrai il numero di elementi DOM e probabilmente avrai la possibilità di semplificare gli stili di pagina.
La profondità del DOM può essere anche un sintomo dei framework che utilizzi. In particolare, i framework basati su componenti, come quelli che si basano su JSX, richiedono di nidificare più componenti in un contenitore principale.
Tuttavia, molti framework ti consentono di evitare il nidificazione dei componenti utilizzando i cosiddetti frammenti. I framework basati su componenti che offrono frammenti come funzionalità includono (a titolo esemplificativo):
Utilizzando i frammenti nel framework che preferisci, puoi ridurre la profondità del DOM. Se temi l'impatto dell'appiattimento della struttura DOM sullo stile, ti consigliamo di utilizzare modalità di layout più moderne (e più veloci) come flexbox o grid.
Altre strategie da valutare
Anche se ti impegni a appiattire la struttura ad albero del DOM e a rimuovere gli elementi HTML non necessari per mantenere il DOM il più piccolo possibile, può comunque essere piuttosto grande e richiedere molto lavoro di rendering man mano che cambia in risposta alle interazioni degli utenti. Se ti trovi in questa situazione, puoi prendere in considerazione alcune altre strategie per limitare il lavoro di rendering.
Valuta la possibilità di adottare un approccio additivo
Potresti trovarti in una situazione in cui parti ampie della pagina non sono inizialmente visibili all'utente al primo rendering. Questa potrebbe essere un'opportunità per eseguire il caricamento lento dell'HTML omettendo le 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 forse anche dopo. Per il caricamento iniziale della pagina, dovrai eseguire meno lavoro di rendering in anticipo, il che significa che il payload HTML iniziale sarà più leggero e verrà visualizzato più rapidamente. In questo modo, le interazioni durante questo periodo cruciale avranno più opportunità di essere pubblicate con meno concorrenza per l'attenzione del thread principale.
Se molte parti della pagina sono inizialmente nascoste al caricamento, potresti anche velocizzare altre interazioni che attivano il ricreamento. Tuttavia, man mano che altre interazioni aggiungono elementi al DOM, il lavoro di rendering aumenta con la crescita del DOM durante il ciclo di vita della pagina.
L'aggiunta di elementi al DOM nel tempo può essere complicata e comporta dei compromessi. Se scegli questa strada, probabilmente stai inviando richieste di rete per ottenere i dati da inserire nel codice HTML che intendi aggiungere alla pagina in risposta a un'interazione dell'utente. Sebbene le richieste di rete in corso non vengano conteggiate ai fini dell'INP, possono aumentare la latenza percepita. Se possibile, mostra un'animazione di caricamento o un altro indicatore che indichi che i dati vengono recuperati, in modo che gli utenti comprendano che sta succedendo qualcosa.
Limita la complessità dei selettori CSS
Quando il browser analizza i selettori nel CSS, deve attraversare la struttura DOM per capire come e se questi selettori si applicano al layout corrente. Più questi selettori sono complessi, maggiore è il lavoro che il browser deve svolgere per eseguire sia il rendering iniziale della pagina sia un numero maggiore di ricalcoli degli stili e del layout se la pagina cambia a seguito di un'interazione.
Utilizza la proprietà content-visibility
CSS offre la proprietà content-visibility
, che è un modo efficace per eseguire il rendering lento degli elementi DOM fuori schermo. Quando gli elementi si avvicinano al viewport, vengono visualizzati on demand. I vantaggi di content-visibility
non riducono solo in modo significativo il lavoro di rendering del rendering iniziale della pagina, ma evitano anche il lavoro di rendering per gli elementi offscreen quando il DOM della pagina viene modificato in seguito a un'interazione dell'utente.
Conclusione
Ridurre le dimensioni del DOM solo a quelle strettamente necessarie è un buon modo per ottimizzare l'INP del tuo sito web. In questo modo, puoi ridurre il tempo necessario al browser per eseguire il layout e il rendering quando il DOM viene aggiornato. Anche se non puoi ridurre in modo significativo le dimensioni del DOM, esistono alcune tecniche che puoi utilizzare per isolare il lavoro di rendering in un sottoalbero DOM, ad esempio il contenimento CSS e la proprietà CSS content-visibility
.
In ogni caso, creare un ambiente in cui il lavoro di rendering sia ridotto al minimo, oltre a ridurre la quantità di lavoro di rendering eseguita dalla pagina in risposta alle interazioni, avrà come risultato un sito web più reattivo per gli utenti quando interagiscono con esso. Ciò significa che avrai un INP inferiore per il tuo sito web, il che si traduce in un'esperienza utente migliore.