Risolvere i problemi di memoria

Scopri come utilizzare Chrome e DevTools per individuare i problemi di memoria che influiscono sulle prestazioni delle pagine, tra cui: perdite di memoria, eccesso di memoria e frequenti garbage collection.

Riepilogo

  • Scopri quanta memoria è attualmente in uso nella tua pagina grazie al Task Manager di Chrome.
  • Visualizza l'utilizzo della memoria nel tempo con le registrazioni degli Spostamenti.
  • Identifica alberi DOM scollegati (una causa comune di fughe di memoria) con gli snapshot heap.
  • Scopri quando viene allocata nuova memoria nell'heap di JS con le registrazioni degli Spostamenti di allocazione.

Panoramica

Nello spirito del modello di prestazioni RAIL, le attività legate alle prestazioni devono concentrarsi su i tuoi utenti.

I problemi di memoria sono importanti perché spesso sono percepiti dagli utenti. Gli utenti possono percepire la memoria di questi problemi:

  • Il rendimento di una pagina peggiora progressivamente. Possibilmente questo è un sintomo di di fuga di memoria. Una fuga di memoria si verifica quando un bug nella pagina fa sì che la pagina utilizzi progressivamente più memoria nel tempo.
  • Il rendimento di una pagina è costantemente scadente. Potrebbe trattarsi di un sintomo di gonfiore della memoria. Memoria si verifica quando una pagina utilizza più memoria di quella necessaria per una velocità della pagina ottimale.
  • Le prestazioni di una pagina vengono ritardate o sembrano essere messe in pausa frequentemente. Questo potrebbe essere un sintomo di garbage collection frequenti. La garbage collection si verifica quando il browser recupera memoria. Il browser decide quando succede. Durante le raccolte, l'esecuzione dello script è messa in pausa. Quindi se il browser garbage collection molto, l'esecuzione dello script sarà molto messa in pausa.

Eccesso di memoria: quanto è "troppo"?

Una perdita di memoria è facile da definire. Se un sito utilizza progressivamente più memoria, una fuga di dati. Ma la memoria gonfia è un po' più difficile da fissare. Cosa si intende per "utilizzo eccessivo di memoria"?

Non ci sono numeri reali qui, perché dispositivi e browser diversi hanno funzionalità diverse. La stessa pagina che funziona perfettamente su uno smartphone di fascia alta potrebbe arrestarsi in modo anomalo su uno smartphone di fascia bassa.

In questo caso, il segreto è usare il modello RAIL e concentrarsi sugli utenti. Scopri quali sono i dispositivi più diffusi con i tuoi utenti, per poi testare la pagina su questi dispositivi. Se l'esperienza è coerente la memoria potrebbe superare le capacità di memoria di questi dispositivi.

Monitora l'utilizzo della memoria in tempo reale con Chrome Task Manager

Utilizza Task Manager di Chrome come punto di partenza per l'indagine sui problemi di memoria. Task Manager è un monitoraggio in tempo reale che indica la quantità di memoria attualmente utilizzata da una pagina.

  1. Premi Maiusc+Esc o vai al menu principale di Chrome e seleziona Altri strumenti > Task Manager per apri Task Manager.

    Apertura di Task Manager

  2. Fai clic con il tasto destro del mouse sull'intestazione della tabella di Task Manager e attiva Memoria JavaScript.

    Attivazione della memoria JS in corso...

Queste due colonne indicano informazioni diverse sull'utilizzo della memoria da parte della pagina:

  • La colonna Memoria rappresenta la memoria nativa. I nodi DOM sono archiviati nella memoria nativa. Se questo aumenta, si stanno creando nodi DOM.
  • La colonna Memoria JavaScript rappresenta l'heap di JS. Questa colonna contiene due valori. La che ti interessa è il numero in tempo reale (il numero tra parentesi). Il numero reale rappresenta la quantità di memoria utilizzata dagli oggetti raggiungibili sulla pagina. Se questo numero è aumentando, si stanno creando nuovi oggetti o quelli esistenti stanno crescendo.

Visualizza le fughe di memoria con le registrazioni delle prestazioni

Puoi anche utilizzare il riquadro Rendimento come punto di partenza per l'indagine. La performance consente di visualizzare l'utilizzo della memoria di una pagina nel tempo.

  1. Apri il riquadro Rendimento in DevTools.
  2. Attiva la casella di controllo Memoria.
  3. Effettua una registrazione.
di Gemini Advanced.

Per dimostrare le registrazioni della memoria delle prestazioni, considera il codice seguente:

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 una stringa di un milione di caratteri x viene inviata all'array x. L'esecuzione di questo codice produce una registrazione della sequenza temporale come il seguente screenshot:

esempio di crescita semplice

Innanzitutto, una spiegazione dell'interfaccia utente. Il grafico HEAP nel riquadro Panoramica (sotto NET) rappresenta l'heap di JS. Sotto il riquadro Panoramica è presente il riquadro Contatore. Qui puoi vedere l'utilizzo della memoria suddiviso per heap JS (come il grafico HEAP nel riquadro Panoramica), nodi DOM, listener e memoria GPU. Se viene disattivata, una casella di controllo la nasconde nel grafico.

Ora, un'analisi del codice confrontata con lo screenshot. Se osservi il contatore dei nodi (il verde) puoi vedere che corrisponde perfettamente al codice. Il numero di nodi aumenta passaggi discreti. Puoi presumere che ogni aumento del conteggio dei nodi sia una chiamata a grow(). JS il grafico heap (il grafico blu) non è così diretto. In linea con le best practice, il primo calo è in realtà una garbage collection forzata (ottenuta premendo il pulsante collect garbage). Come l'avanzamento della registrazione, puoi vedere che le dimensioni dell'heap JS aumentano. Si tratta di un comportamento normale e previsto: Il codice JavaScript crea i nodi DOM a ogni clic di un pulsante e svolge molto lavoro quando crea la stringa con un milione di caratteri. L'aspetto fondamentale è il fatto che l'heap JS termina superiore a quello iniziale (il "inizio" qui è il punto successivo alla garbage collection forzata). Nella Nel mondo reale, se vedessi questo modello di aumento della dimensione dell'heap di JS o della dimensione del nodo, significano potenzialmente una perdita di memoria.

Scopri le perdite di memoria ad albero DOM scollegate con gli snapshot dell'heap

Un nodo DOM può essere garbage collection solo quando non esistono riferimenti al nodo dall'interfaccia struttura DOM o codice JavaScript. Un nodo viene detto "scollegato" quando viene rimosso dall'albero DOM, qualche codice JavaScript vi fa ancora riferimento. I nodi DOM scollegati sono una causa comune di perdite di memoria. Questo ti insegna a usare DevTools profiler heap 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);

Facendo clic sul pulsante a cui si fa riferimento nel codice viene creato un nodo ul con dieci li figlio. Questi nodi a cui fa riferimento il codice, ma non esistono nell'albero DOM, quindi vengono scollegate.

Gli snapshot dell'heap sono un modo per identificare i nodi scollegati. Come suggerisce il nome, gli snapshot dell'heap mostrano il modo in cui la memoria è distribuita tra gli oggetti JS e i nodi DOM della tua pagina nel momento in cui senza dover creare uno snapshot.

Per creare uno snapshot, apri DevTools e vai al riquadro Memoria, seleziona l'icona Heap Pulsante di opzione Istantanea, quindi premi il pulsante Crea istantanea.

acquisisci istantanea heap

L'elaborazione e il caricamento dello snapshot potrebbero richiedere del tempo. Al termine, selezionalo nella parte sinistra (denominato HEAP SNAPSHOTS).

Digita Detached nella casella di testo Filtro classe per cercare strutture DOM scollegate.

filtrando i nodi scollegati

Espandi i carati per esaminare un albero staccato.

indagando su un albero staccato

I nodi evidenziati in giallo hanno riferimenti diretti dal codice JavaScript. Nodi evidenziati rosso non hanno riferimenti diretti. Sono vivi solo perché fanno parte del albero di Natale. In generale, conviene concentrarsi sui nodi gialli. Correggi il codice in modo che il nodo giallo più a lungo del necessario e ti eliminerai anche dai nodi rossi che fanno parte all'albero giallo del nodo.

Fai clic su un nodo giallo per effettuare ulteriori accertamenti. Nel riquadro Oggetti puoi vedere altro informazioni sul codice che vi fa riferimento. Ad esempio, nel seguente screenshot puoi vedere che la variabile detachedTree faccia riferimento al nodo. Per correggere questa particolare perdita di memoria, studierebbe il codice che utilizza detachedTree e si assicura che rimuova il suo riferimento al nodo quando non è più necessario.

indaga su un nodo giallo

Identifica le perdite di memoria heap di JS con gli Spostamenti di allocazione

La sequenza temporale di allocazione è un altro strumento che consente di tenere traccia delle perdite di memoria nell'heap di JS.

Per dimostrare la sequenza temporale 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 eseguito il push del pulsante a cui viene fatto riferimento nel codice, viene generata una stringa di un milione di caratteri aggiunto all'array x.

Per registrare una sequenza temporale di allocazione, apri DevTools, vai al riquadro Profili e seleziona Record Cronologia di allocazione, premi il pulsante Avvia ed esegui l'azione sospetta sta causando la perdita di memoria, quindi premi il pulsante interrompi registrazione (pulsante interrompi la registrazione) quando hai finito.

Mentre registri, controlla se nella sequenza temporale di allocazione vengono visualizzate delle barre blu, come screenshot qui sotto.

nuove allocazioni

Queste barre blu rappresentano le nuove allocazioni della memoria. Queste nuove allocazioni di memoria sono i tuoi candidati per le fughe di memoria. Puoi eseguire lo zoom su una barra per filtrare il riquadro Costruttore e mostrare solo gli oggetti che sono stati assegnati durante il periodo di tempo specificato.

sequenza temporale di allocazione ingrandita

Espandi l'oggetto e fai clic sul relativo valore per visualizzarne i dettagli nel riquadro Oggetto. Per nello screenshot seguente, visualizzando i dettagli dell'oggetto appena allocato, vedrai che è stata allocata alla variabile x nell'ambito Window.

dettagli dell&#39;oggetto

Analizzare l'allocazione della memoria in base alla funzione

Utilizza il tipo Allocation Sampling (Campionamento di allocazione) nel riquadro Memory (Memoria) per visualizzare l'allocazione della memoria in base alla funzione JavaScript.

Profiler allocazione dei record

  1. Seleziona il pulsante di opzione Allocation Sampling (Campionamento di allocazione). Se nella pagina c'è un worker, puoi selezionarlo come target di profilazione utilizzando il menu a discesa accanto al pulsante Inizia.
  2. Premi il pulsante Avvia.
  3. Esegui le azioni sulla pagina che vuoi esaminare.
  4. Una volta completate tutte le azioni, premi il pulsante Interrompi.

DevTools mostra un'analisi dell'allocazione della memoria per funzione. La visualizzazione predefinita è Intensa (in basso) Su), che mostra le funzioni che hanno allocato più memoria in alto.

Profilo di allocazione

Individua garbage collection frequente

Se la tua pagina viene messa in pausa frequentemente, potrebbero esserci problemi di garbage collection.

Per individuare i rifiuti frequenti, puoi utilizzare le registrazioni della memoria di Chrome Task Manager o Spostamenti raccolte. Nel Task Manager, le dimensioni di Memoria o Memoria JavaScript aumentano o diminuiscono di frequente. di garbage collection frequenti. Nelle registrazioni degli Spostamenti, con frequenza in aumento e in diminuzione I grafici dell'heap o dei nodi JS indicano garbage collection frequenti.

Una volta identificato il problema, puoi utilizzare una registrazione della sequenza temporale di allocazione per scoprire dove alla memoria allocata e alle funzioni che causano le allocazioni.