Per migliorare i tempi di risposta delle UI, React mette a disposizione un componente chiamato React.memo. Quando viene utilizzato questo componente, React memorizza lo stato del componente a cui è collegato React.memo e renderizza soltanto le parti necessarie, skippando quelle che non sono necessarie.
E’ comunque da tenere in considereazione che spesso questo tipo di ottimizzazione non è necessario in quanto React è già sufficientemente performante.
In pratica, consente di migliorare le performance nella visualizzazione di un componente.
Durante la fase di modifica del DOM, React prima effettua il render del componente, successivamente verifica il render con il render precedente, e solo nel caso in cui ci siano delle differenze, effettua l’aggiornamento del DOM.
La fase di comparazione tra il render precedente ed il render corrente è normalmente “veloce”, ma in alcune condizioni può essere ottimizzata rendendola di fatto “ultra-veloce”.
Utilizzando React.memo(…), React memorizza il render di un componente e solo nel caso in cui non si siano verificati degli aggiornamenti nelle props, non effettua il nuovo render.
Analizziamo il seguente codice:
export function Movie({ title, releaseDate }) {
return (
<div>
<div>Movie title: {title}</div>
<div>Release date: {releaseDate}</div>
</div>
);
}
export const MemoizedMovie = React.memo(Movie);Nell’ultima riga si nota l’export del compoente, utilizzando React.memo(…).
Il funzionamento del componente è esattamente lo stesso di un componente tradizionale, con la sola differenza che il componente viene memorizzato. Nell’esempio React utilizzerà la copia in memoria del componente fino a quando title e releaseDate non verranno modificate.
In questo modo si ottiene un miglioramento in termini di velocità nella fase del render del componente. Questo tipo di comportamento si può ottenere anche creando un “class component” PureComponent.
E’ possibile personalizzare la funzione di comparazione delle props utilizzata da React.memo() .
In particolare React.memo accetta un secondo parametro (opzionale) dove specificare la funzione per la comparazione. Questa funzione dovrà restituire true oppure false a seconda che le props siano uguali o differenti. Questa è la definizione completa:
React.memo(Component, [areEqual(prevProps, nextProps)]);
A questo punto la domanda sorge spontanea: quando utilizzare React.memo ?
E’ consigliato usare React.memo quando :
- Quanto il componente è functional e con le stesse props. In pratica quanto l’output è sempre lo stesso
- Quando un componente viene renderizzato spesso
- Quanto il nostro componente viene re-renderizzato con le stesse props
- Quanto il componente contiene un numero elevato di elementi di UI che rendeno necessaria la comparazione delle props
The more often the component renders with the same props, the heavier and the more computationally expensive the output is, the more chances are that component needs to be wrapped in
React.memo().
Non è consigliato utilizzare React.memo quando:
- Il componente non è particolarmente pesante, e ha props che si aggiornano molto frequentemente
- Non è possibile quantificare il miglioramento delle prestazioni: vale la regola che se non è possibile quantificare il miglioramento delle prestazioni utilizzando React.memo() è meglio non utilizzarlo. L’introduzione di React.memo comporta l’esecuzione di due attivita: l’attività di confronto e l’attività di render nel caso in cui siano state riscontrate delle differenze tra le props. Nel caso in cui il cambiamento sia piuttosto frequente, oltre alle operazioni tradizionali viene anche eseguita l’operazione di confronto. Nel caso opposto, quindi quando siamo certi che non si verificheranno cambiamenti nelle props, non vi è ragione di eseguire la funzione di comparazione (e quindi usare React.memo).