Scopri come utilizzare Chrome e DevTools per trovare problemi di memoria che influiscono sulle prestazioni della pagina, tra cui perdite di memoria, sovraccarico di memoria e garbage collection frequenti.
Riepilogo
- Scopri quanta memoria utilizza la tua pagina con Task Manager di Chrome.
- Visualizza la memoria utilizzata nel tempo con le registrazioni della cronologia.
- Identifica gli alberi DOM scollegati (una causa comune di perdite di memoria) con le istantanee heap.
- Scopri quando viene allocata nuova memoria nello heap JS con le registrazioni della cronologia di allocazione.
- Identifica gli elementi scollegati conservati dal riferimento JavaScript.
Panoramica
In linea con lo spirito del modello di prestazioni RAIL, l'attenzione dei tuoi sforzi per migliorare le prestazioni dovrebbe essere rivolta ai tuoi utenti.
I problemi di memoria sono importanti perché spesso sono percepibili dagli utenti. Gli utenti possono percepire i problemi di memoria nei seguenti modi:
- Il rendimento di una pagina peggiora progressivamente nel tempo. Questo è probabilmente un sintomo di una perdita di memoria. Una perdita di memoria si verifica quando un bug nella pagina fa sì che questa utilizzi progressivamente sempre più memoria nel tempo.
- Le prestazioni di una pagina sono costantemente scadenti. Questo è probabilmente un sintomo di un eccesso di memoria. Il bloat della memoria si verifica quando una pagina utilizza più memoria del necessario per una Page Speed ottimale.
- Le prestazioni di una pagina sono ritardate o sembrano interrompersi di frequente. Questo è probabilmente un sintomo di frequenti garbage collection. La garbage collection è il momento in cui il browser recupera la memoria. Il browser decide quando ciò avviene. Durante le raccolte, l'esecuzione di tutti gli script viene messa in pausa. Quindi, se il browser esegue spesso la garbage collection, l'esecuzione dello script verrà messa in pausa di frequente.
Memory bloat: how much is "too much"?
Una perdita di memoria è facile da definire. Se un sito utilizza progressivamente sempre più memoria, significa che c'è una perdita. Tuttavia, il bloat della memoria è un po' più difficile da individuare. Che cosa si intende per "utilizza troppa memoria"?
Non esistono numeri precisi, perché dispositivi e browser diversi hanno funzionalità diverse. La stessa pagina che funziona senza problemi su uno smartphone di fascia alta potrebbe arrestarsi in modo anomalo su uno smartphone di fascia bassa.
La chiave è utilizzare il modello RAIL e concentrarsi sugli utenti. Scopri quali dispositivi sono più utilizzati dai tuoi utenti e testa la tua pagina su questi dispositivi. Se l'esperienza è costantemente negativa, la pagina potrebbe superare le capacità di memoria di questi dispositivi.
Monitora l'utilizzo della memoria in tempo reale con Task Manager di Chrome
Utilizza il Task Manager di Chrome come punto di partenza per l'indagine sui problemi di memoria. Il Gestore dei processi è un monitor in tempo reale che ti indica la quantità di memoria utilizzata da una pagina.
Premi Maiusc+Esc o vai al menu principale di Chrome e seleziona Altri strumenti > Gestione attività per aprire Gestione attività.

Fai clic con il tasto destro del mouse sull'intestazione della tabella di Gestione attività e attiva Memoria JavaScript.

Queste due colonne forniscono informazioni diverse su come la pagina utilizza la memoria:
- La colonna Footprint della memoria rappresenta la memoria del sistema operativo. I nodi DOM vengono archiviati nella memoria del sistema operativo. Se questo valore aumenta, significa che vengono creati nodi DOM.
La colonna Memoria JavaScript rappresenta l'heap JS. Questa colonna contiene due valori. Il valore che ti interessa è il numero di spettatori in tempo reale (il numero tra parentesi). Il numero di oggetti attivi rappresenta la quantità di memoria utilizzata dagli oggetti raggiungibili nella pagina. Se questo numero aumenta, significa che vengono creati nuovi oggetti o che quelli esistenti stanno crescendo.

Visualizza le perdite di memoria con le registrazioni di Performance
Puoi anche utilizzare il riquadro Prestazioni come un altro punto di partenza per la tua indagine. Il riquadro Prestazioni ti aiuta a visualizzare l'utilizzo della memoria di una pagina nel tempo.
- Apri il riquadro Prestazioni in DevTools.
- Attiva la casella di controllo Memoria.
- Crea una registrazione.
Per mostrare le registrazioni della memoria di Prestazioni, considera il seguente codice:
var x = [];
function grow() {
for (var i = 0; i < 10000; i++) {
document.body.appendChild(document.createElement('div'));
}
x.push(new Array(1000000).join('x'));
}
document.getElementById('grow').addEventListener('click', grow);
Ogni volta che viene premuto il pulsante a cui viene fatto riferimento nel codice, vengono aggiunti diecimila nodi div al corpo del documento e viene inserita una stringa di un milione di caratteri x nell'array x.
L'esecuzione di questo codice produce una registrazione della cronologia come quella nello screenshot seguente:

Innanzitutto, una spiegazione dell'interfaccia utente. Il grafico HEAP nel riquadro Panoramica (sotto NET) rappresenta l'heap JS. Sotto il riquadro Panoramica si trova il riquadro Contatore. Qui puoi vedere la memoria utilizzata suddivisa per heap JS (come il grafico HEAP nel riquadro Panoramica), documenti, nodi DOM, listener e memoria GPU. Se disattivi una casella di controllo, questa viene nascosta dal grafico.
Ora, un'analisi del codice rispetto allo screenshot. Se guardi il contatore dei nodi (il grafico verde), puoi vedere che corrisponde esattamente al codice. Il numero di nodi aumenta in passaggi discreti. Puoi presumere che ogni aumento del numero di nodi sia una chiamata a grow(). Il grafico dell'heap JS (il grafico blu) non è così semplice. In linea con le best practice, il primo calo è in realtà una garbage collection forzata (ottenuta premendo il pulsante Esegui garbage collection). Man mano che la registrazione procede, puoi vedere che le dimensioni dell'heap JS aumentano. Questo è naturale e previsto: il codice JavaScript crea i nodi DOM a ogni clic sul pulsante e svolge un lavoro significativo quando crea la stringa di un milione di caratteri. L'aspetto fondamentale è che l'heap JS termina con un valore più alto rispetto a quello iniziale (dove "iniziale" è il punto dopo la garbage collection forzata). Nel mondo reale, se vedessi questo pattern di aumento delle dimensioni dello heap JS o dei nodi, potrebbe significare una perdita di memoria.
Scopri le perdite di memoria dell'albero DOM scollegato con le istantanee heap
Un nodo DOM può essere sottoposto a garbage collection solo quando non esistono riferimenti a questo nodo nell'albero DOM della pagina o nel codice JavaScript. Un nodo viene definito "scollegato" quando viene rimosso dall'albero DOM, ma alcuni JavaScript vi fanno ancora riferimento. I nodi DOM scollegati sono una causa comune di perdite di memoria. Questa sezione spiega come utilizzare i profiler heap di DevTools per identificare i nodi scollegati.
Ecco un semplice esempio di nodi DOM scollegati.
var detachedTree;
function create() {
var ul = document.createElement('ul');
for (var i = 0; i < 10; i++) {
var li = document.createElement('li');
ul.appendChild(li);
}
detachedTree = ul;
}
document.getElementById('create').addEventListener('click', create);
Se fai clic sul pulsante a cui fa riferimento il codice, viene creato un nodo ul con dieci elementi secondari li. Questi nodi sono referenziati dal codice, ma non esistono nell'albero DOM, quindi sono scollegati.
Le istantanee heap sono un modo per identificare i nodi scollegati. Come suggerisce il nome, le istantanee heap mostrano come viene distribuita la memoria tra gli oggetti JS e i nodi DOM della pagina al momento dell'istantanea.
Per creare un'istantanea, apri DevTools e vai al riquadro Memoria, seleziona il pulsante di opzione Istantanea heap, quindi premi il pulsante Crea istantanea.

L'elaborazione e il caricamento dello snapshot potrebbero richiedere un po' di tempo. Al termine, selezionalo dal riquadro a sinistra (denominato Istantanee heap).
Digita Detached nella casella di immissione Filtro classe per cercare gli alberi DOM scollegati.

Espandi i simboli di accento circonflesso per esaminare un albero scollegato.

Fai clic su un nodo per esaminarlo più nel dettaglio. Nel riquadro Oggetti puoi visualizzare ulteriori informazioni sul codice che fa riferimento all'oggetto. Ad esempio, nello screenshot seguente puoi vedere che la variabile detachedTree fa riferimento al nodo. Per correggere questa specifica perdita di memoria, devi studiare il codice che utilizza detachedTree e assicurarti che rimuova il riferimento al nodo quando non è più necessario.

Identifica le perdite di memoria heap JS con le cronologie di allocazione
La cronologia di allocazione è un altro strumento che può aiutarti a rintracciare le perdite di memoria nell'heap JS.
Per mostrare la Cronologia di allocazione, considera il seguente codice:
var x = [];
function grow() {
x.push(new Array(1000000).join('x'));
}
document.getElementById('grow').addEventListener('click', grow);
Ogni volta che viene premuto il pulsante a cui fa riferimento il codice, viene aggiunta una stringa di un milione di caratteri all'array x.
Per registrare una cronologia di allocazione, apri DevTools, vai al riquadro Memoria, seleziona il pulsante di opzione Allocazioni sulla cronologia, premi il pulsante Registra, esegui l'azione che sospetti stia causando la perdita di memoria e poi premi il pulsante Interrompi registrazione quando hai finito.
Durante la registrazione, controlla se vengono visualizzate barre blu nella sequenza temporale di allocazione, come nello screenshot seguente.

Le barre blu rappresentano le nuove allocazioni della memoria. Queste nuove allocazioni della memoria sono i candidati per le perdite di memoria. Puoi aumentare lo zoom su una barra per filtrare il riquadro Costruttore in modo da visualizzare solo gli oggetti allocati durante il periodo di tempo specificato.

Espandi l'oggetto e fai clic sul relativo valore per visualizzare ulteriori dettagli nel riquadro Oggetto. Ad esempio, nello screenshot di seguito, visualizzando i dettagli dell'oggetto appena allocato, puoi vedere che è stato allocato alla variabile x nell'ambito Window.

Esamina l'allocazione della memoria per funzione
Utilizza il tipo di profilo Campionamento allocazione nel riquadro Memoria per visualizzare l'allocazione della memoria in base alla funzione JavaScript.

- Seleziona il pulsante di opzione Campionamento dell'allocazione. Se nella pagina è presente un worker, puoi selezionarlo come target di profilazione dalla finestra Seleziona istanza VM JavaScript.
- Premi il pulsante Inizia.
- Esegui le azioni sulla pagina che vuoi esaminare.
- Premi il pulsante Interrompi quando hai terminato tutte le azioni.
DevTools mostra una suddivisione dell'allocazione della memoria per funzione. La visualizzazione predefinita è Pesante (dal basso verso l'alto), che mostra in alto le funzioni che hanno allocato più memoria.

Identifica gli oggetti conservati dal riferimento JS
Il profilo Elementi scollegati mostra gli elementi scollegati che persistono perché sono referenziati dal codice JavaScript.
Registra un profilo Elementi scollegati per visualizzare i nodi HTML esatti e il numero di nodi.

Individua le garbage collection frequenti
Se la pagina sembra interrompersi di frequente, potresti avere problemi di garbage collection.
Puoi utilizzare il Task Manager di Chrome o le registrazioni della memoria della cronologia per individuare le garbage collection frequenti. In Task Manager, i valori di Memoria o Memoria JavaScript che aumentano e diminuiscono di frequente rappresentano frequenti garbage collection. Nelle registrazioni della cronologia, i grafici dello heap JS o del conteggio dei nodi che salgono e scendono di frequente indicano frequenti garbage collection.
Una volta identificato il problema, puoi utilizzare una registrazione della cronologia di allocazione per scoprire dove viene allocata la memoria e quali funzioni causano le allocazioni.