Vai al contenuto

React, DOM e DOM Virtuale: quali differenze?

Prima di parlare di DOM Virtuale e React, cerchiamo di fissare un paio di concetti: DOM sta per Document Object Model ed è un’astrazione di un testo strutturato.

Per gli sviluppatori web, questo testo è una semplice pagina HTML, e il DOM è semplicemente chiamato DOM HTML. Gli elementi di HTML diventano nodi nel DOM.

Quindi, mentre l’HTML è un testo, il DOM è una rappresentazione in memoria di questo testo. Potremmo confrontarlo alla stregua di un processo informatico, che si tratta di un’istanza di un programma. Possiamo avere più processi dello stesso programma, cosi come possiamo avere più DOM dello stesso codice HTML (ad esempio la stessa pagina caricata su molte schede).

Il DOM HTML fornisce un’interfaccia (API) per attraversare e manipolare i nodi in vari modi: come aggiungere nodi, rimuovere nodi, modificare il contenuto di un nodo… Il DOM HTML contiene metodi come getElementById removeChild. Di solito si utilizza  JavaScript per lavorare con il DOM. Quindi, ogni volta che vogliamo modificare dinamicamente il contenuto della pagina web, modifichiamo il DOM:

var item = document.getElementById("myLI");
item.parentNode.removeChild(item);

document rappresenta un’astrazione del nodo radice, mentre getElementByIdparentNoderemoveChild sono metodi dall’API DOM HTML.

Problemi di inefficienza

Il DOM HTML è sempre strutturato ad albero e ciò è utile perchè possiamo attraversare gli alberi abbastanza facilmente. Sfortunatamente, facilmente non significa rapidamente.  La manipolazione del DOM tende ad essere piuttosto inefficiente in quanto il DOM era originariamente previsto per le interfacce utente statiche: pagine HTML restituite dal server che non richiedevano aggiornamenti dinamici. Quando il DOM si aggiorna, deve aggiornare il nodo e renderizzare la pagina con il CSS e il layout corrispondenti.

Con la crescente diffusione delle Single Page Apps (SPA), i componenti della nostra pagina sono sempre più responsabili dell’ascolto degli aggiornamenti e del re-rendering degli aggiornamenti nell’interfaccia utente, quindi un continuo modificare dell’albero DOM. Non è raro imbattersi in pagine che visualizzano migliaia di nodi generati dinamicamente che devono anche continuare ad ascoltare gli aggiornamenti futuri. E’ qui dove le cose possono diventare piuttosto “costose” dal punto di vista delle prestazioni e dello sviluppo.

Facciamo un esempio.

Stiamo sviluppando una SPA (che non è un centro benessere, ma una single page apps), quindi il nostro DOM sarà costituito da migliaia di elementi DIV. Abbiamo molti metodi che gestiscono gli eventi: clic, submit, change… Se utilizziamo una libreria per gestire gli eventi tipo jQuery, dovremmo implementare le istruzioni in modo che:

  • trova ogni nodo interessato a un evento
  • aggiornalo se necessario

E’ tutto abbastanza lecito, direte voi… Ma supponiamo di avere un elenco di elementi: all’interno di questo elenco abbiamo un numero di elementi e il contenuto di ognuno di questi elementi può essere aggiornato. Se viene aggiornato uno di questi elementi dell’elenco, il DOM esegue nuovamente il rendering dell’intero elenco. È da qui che deriva l’inefficienza del DOM: potrebbe diventare incredibilmente inefficiente se si dispone di una SPA con centinaia o migliaia di componenti che richiedono il re-rendering quando avvengono degli aggiornamenti. In teoria invece, ci piacerebbe solo ri-renderizzare gli elementi che ricevono aggiornamenti, lasciando il resto degli elementi così come sono.

React e Virtual DOM

Come risolviamo dunque il problema delle prestazioni? Questo è esattamente il punto in cui il Virtual DOM entra in azione assieme a React (reactjs.org), una libreria specifica creata da Facebook per cercare di risolvere tutti i problemi legati alle interfacce grafiche in HTML.

Il Virtual DOM è un’astrazione leggera del DOM. Puoi considerarlo come una copia del DOM, che può essere aggiornato senza influenzare il DOM reale. Ha tutte le stesse proprietà del vero oggetto DOM, ma non ha la capacità di scrivere sullo schermo come il vero DOM. Il DOM virtuale guadagna velocità ed efficienza dal fatto che è leggero. Di fatto, un nuovo DOM virtuale viene creato dopo ogni ri-rendering. Poiché il DOM stesso era già un’astrazione, il DOM virtuale è, in realtà, un’astrazione di un’astrazione. Forse è meglio pensare al DOM virtuale come alla copia locale e semplificata del DOM HTML…

Prima di tutto, il Virtual DOM non è stato inventato da React, ma React lo utilizza e fornisce delle librerie per gestirlo in maniera gratuita.

Con React non è necessario ricorrere alle funzionalità del DOM per modificare gli elementi della pagina: è sufficiente cambiare le informazioni contenute all’interno dell’oggetto che rappresenta il modello dei dati, rappresentato dallo statoin React, per ottenere l’aggiornamento automatico dell’interfaccia utente.

Quando si verifica un evento ed è necessario reagire modificando gli elementi della pagina, React aggiorna il Virtual DOM; successivamente analizza il precedente stato del Virtual DOM con lo stato nuovo ottenuto dall’applicazione  delle modifiche, quindi viene aggiornato il DOM reale applicando solo gli effettivi cambiamenti. Calcolare le differenze tra il precedente stato e il corrente stato del Virtual DOM è estremamente veloce e grazie a esso si limitano al minimo gli interventi sul DOM reale, la cui manipolazione è molto più lenta, ottenendo cosi un incremento delle performance.