Cómo solucionar problemas de memoria

Kayce Basques
Kayce Basques

Aprende a usar Chrome y Herramientas para desarrolladores para encontrar problemas de memoria que afecten el rendimiento de la página, como las siguientes: fugas de memoria, aumentos de memoria y recolecciones frecuentes de elementos no utilizados.

Resumen

  • Descubre cuánta memoria usa tu página actualmente con el Administrador de tareas de Chrome.
  • Visualizar el uso de memoria en el tiempo con grabaciones de Rutas
  • Identifica árboles separados del DOM (una causa común de fugas de memoria) con capturas de pantalla del montón.
  • Averigua cuándo se asigna memoria nueva a tu montón JS con grabaciones de líneas de tiempo de asignación.

Descripción general

Según el espíritu del modelo de rendimiento RAIL, el enfoque de las iniciativas de rendimiento debe ser tus usuarios.

Los problemas de memoria son importantes porque, a menudo, los usuarios los pueden percibir. Los usuarios pueden percibir la memoria problemas de las siguientes maneras:

  • El rendimiento de una página empeora progresivamente con el tiempo. Es posible que esto sea un síntoma de fuga de memoria. Una fuga de memoria es cuando un error en la página hace que esta utilice progresivamente más y más memoria con el tiempo.
  • El rendimiento de una página es siempre bajo. Es posible que esto sea un síntoma de un aumento de la memoria. Memoria un sobredimensionamiento es cuando una página usa más memoria de la necesaria para lograr una velocidad óptima.
  • El rendimiento de una página se retrasa o parece detenerse con frecuencia. Es posible que esto sea un síntoma de recolecciones frecuentes de elementos no utilizados. La recolección de elementos no utilizados se produce cuando el navegador reclama memoria. El navegador decide cuándo sucede. Durante la recopilación, la ejecución de todas las secuencias de comandos se detiene. Entonces, si el navegador se realizan muchas recolecciones de elementos no utilizados, se detendrá mucho la ejecución de secuencias de comandos.

Aumento de memoria: ¿cuánto es "demasiado"?

Una fuga de memoria es fácil de definir. Si un sitio utiliza cada vez más memoria, significa que si tenemos una fuga. Pero el sobredimensionamiento de memoria es un poco más difícil de identificar. ¿Qué califica como “usar demasiada memoria”?

No hay números estrictos aquí, ya que los distintos dispositivos y navegadores tienen capacidades diferentes. La misma página que se ejecuta sin problemas en un smartphone de alta gama puede fallar en uno de gama baja.

La clave aquí es usar el modelo RAIL y centrarse en los usuarios. Descubre qué dispositivos son populares con los usuarios y, luego, probar la página en esos dispositivos. Si la experiencia es coherente es posible que la página exceda la capacidad de memoria de esos dispositivos.

Supervisa el uso de la memoria en tiempo real con el Administrador de tareas de Chrome

Usa el Administrador de tareas de Chrome como punto de partida para investigar los problemas de memoria. El Administrador de tareas es un monitor en tiempo real que indica la cantidad de memoria que usa una página en el momento.

  1. Presiona Mayúsculas + Esc o ve al menú principal de Chrome y selecciona Más herramientas > Administrador de tareas para abre el Administrador de tareas.

    Cómo abrir el Administrador de tareas

  2. Haz clic con el botón derecho en el encabezado de la tabla del Administrador de tareas y habilita la memoria de JavaScript.

    Habilita la memoria de JS

Estas dos columnas te brindan información diferente sobre cómo usa la memoria tu página:

  • La columna Memory representa la memoria nativa. Los nodos del DOM se almacenan en la memoria nativa. Si esta está aumentando y se están creando nodos del DOM.
  • La columna JavaScript Memory representa el montón de JS. Esta columna contiene dos valores. El valor que te interesa es el número en tiempo real (el número entre paréntesis). El número publicado representa la cantidad de memoria que usan los objetos accesibles de tu página. Si este número es aumentan, se crean objetos nuevos o crecen los existentes.

Cómo visualizar fugas de memoria con grabaciones de rendimiento

También puedes usar el panel Rendimiento como otro punto de partida en tu investigación. La actuación te ayuda a visualizar el uso de memoria de una página a lo largo del tiempo.

  1. Abre el panel Rendimiento en Herramientas para desarrolladores.
  2. Habilita la casilla de verificación Memory.
  3. Realiza una grabación.

Para demostrar las grabaciones de memoria de rendimiento, ten en cuenta el siguiente código:

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);

Cada vez que se presiona el botón al que se hace referencia en el código, se agregan diez mil nodos div al cuerpo del documento, y se envía una cadena de un millón de caracteres x al array x. Cuando se ejecuta este código, se produce una grabación en Rutas como la que se muestra en la siguiente captura de pantalla:

ejemplo de crecimiento simple

Primero, una explicación de la interfaz de usuario. El gráfico HEAP en el panel Overview (debajo de NET) representa el montón de JS. Debajo del panel Descripción general, se encuentra el panel Contador. Aquí puedes ver el uso de memoria desglosado por montón de JS (igual que el gráfico HEAP en el panel Overview) documentos, nodos del DOM, objetos de escucha y memoria GPU. Si inhabilitas una casilla de verificación, se oculta del gráfico.

Ahora, un análisis del código comparado con la captura de pantalla. Si observas el contador de nodos (el gráfico verde) verás que coincide de forma clara con el código. El recuento de nodos aumenta en pasos discretos. Puedes suponer que cada aumento en el recuento de nodos es una llamada a grow(). El JS el gráfico de montón (el gráfico azul) no es tan sencillo. De acuerdo con las prácticas recomendadas, la primera caída es en realidad una recolección forzada de elementos no utilizados (que se logra presionando el botón recopilar elementos no utilizados). Como mientras avanza la grabación, puede ver que el tamaño del montón de JS tiene un aumento repentino. Esto es natural y esperado: El código JavaScript crea los nodos del DOM con cada clic en un botón y hace mucho trabajo cuando crea la cadena de un millón de caracteres. El aspecto clave aquí es el hecho de que el montón JS más arriba de lo que comenzó (el “comienzo” aquí es el punto después de la recolección forzada de elementos no usados). En el mundo real, si vieras este patrón de aumentar el tamaño del montón de JS o de los nodos, lo que podría significar una fuga de memoria.

Descubre fugas de memoria de árboles separados del DOM con instantáneas del montón

Un nodo del DOM solo puede estar sujeto a la recolección de elementos no utilizados cuando no hay referencias a él en los metadatos de la página Árbol del DOM o código JavaScript. Se dice que un nodo está "desvinculado". cuando se quita del árbol del DOM, pero algunos JavaScript todavía hacen referencia a él. Los nodos del DOM separados son una causa común de fugas de memoria. Esta te enseña a usar las herramientas de desarrollo Generadores de perfiles del montón para identificar los nodos separados.

Este es un ejemplo sencillo de nodos del DOM separados.

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);

Si haces clic en el botón al que se hace referencia en el código, se crea un nodo ul con diez elementos secundarios li. Estos nodos el código hace referencia a ellas, pero no existen en el árbol del DOM, por lo que están separados.

Las instantáneas del montón son una forma de identificar los nodos separados. Como su nombre lo indica, las capturas de pantalla de montón cómo se distribuye la memoria entre los objetos JS de tu página y los nodos del DOM en el momento de la instantánea.

Para crear una instantánea, abre Herramientas para desarrolladores, ve al panel Memoria y selecciona Montón Snapshot y, luego, presiona el botón Take Snapshot.

tomar una instantánea del montón

Es posible que la instantánea tarde un poco en procesarse y cargarse. Cuando termine, selecciónela en el menú de la izquierda llamado HEAP SNAPSHOTS.

Escribe Detached en el cuadro de texto Class filter para buscar árboles del DOM separados.

filtrado para nodos separados

Expande los quilates para investigar un árbol separado.

investigando un árbol separado

Los nodos destacados en amarillo tienen referencias directas a ellos desde el código JavaScript. Nodos destacados rojo no tienen referencias directas. Solo están vivos porque son parte del nodo amarillo de imágenes. En general, debes enfocarte en los nodos amarillos. Corrige el código para que el nodo amarillo no sea estén activos por más tiempo del necesario y también te deshaces de los nodos rojos que son árbol del nodo amarillo.

Haz clic en un nodo amarillo para investigarlo más a fondo. En el panel Objetos, puedes ver más información sobre el código que hace referencia a él. Por ejemplo, en la siguiente captura de pantalla puedes ver que la variable detachedTree hace referencia al nodo. Para solucionar esta fuga de memoria en particular, estudiaría el código que usa detachedTree y se aseguraría de que quite su referencia al nodo. cuando ya no se necesita.

investigar un nodo amarillo

Identifica fugas de memoria del montón de JS con líneas de tiempo de asignación

El cronograma de asignación es otra herramienta que puede ayudarte a rastrear fugas de memoria en el montón JS.

Para demostrar el cronograma de asignación, ten en cuenta el siguiente código:

var x = [];

function grow() {
  x.push(new Array(1000000).join('x'));
}

document.getElementById('grow').addEventListener('click', grow);

Cada vez que se presiona el botón al que se hace referencia en el código, se crea una cadena de un millón de caracteres Se agregó al array x.

Para grabar un cronograma de asignación, abre Herramientas para desarrolladores, ve al panel Profiles y selecciona Record Botón de selección del cronograma de asignación, presiona el botón Iniciar y realiza la acción que sospechas está causando la fuga de memoria y, luego, presiona el botón detener grabación. (botón para detener la grabación) cuando que estás listo.

Mientras grabas, observa si aparecen barras azules en la línea de tiempo de asignación, como en captura de pantalla a continuación.

asignaciones nuevas

Las barras azules representan asignaciones de memoria nuevas. Esas nuevas asignaciones de memoria son tus opciones en busca de fugas de memoria. Puedes hacer zoom en una barra para filtrar el panel Constructor de modo que solo muestre los objetos que se asignaron durante el período especificado.

cronograma de asignación ampliado

Expande el objeto y haz clic en su valor para ver más detalles en el panel Objeto. Para ejemplo, en la siguiente captura de pantalla, visualizando los detalles del objeto que se asignó recientemente, podrás ver que se asignó a la variable x en el alcance Window.

detalles del objeto

Investiga la asignación de memoria por función

Usa el tipo Allocation Sampling en el panel Memory para ver la asignación de memoria por función de JavaScript.

Generador de perfiles de asignación de registros

  1. Elige el botón de selección Allocation Sampling. Si hay un trabajador en la página, puedes seleccionarlo como el objetivo de generación de perfiles usando el menú desplegable junto al botón Start.
  2. Presiona el botón Start.
  3. Realiza las acciones en la página que deseas investigar.
  4. Presiona el botón Detener cuando hayas finalizado todas las acciones.

Las Herramientas para desarrolladores te muestran un desglose de la asignación de memoria por función. La vista predeterminada es Intensas (inferior Up), que muestra las funciones que asignaron la mayor cantidad de memoria en la parte superior.

Perfil de asignación

Identifica recolecciones frecuentes de elementos no utilizados

Si tu página parece detenerse con frecuencia, es posible que tengas problemas de recolección de elementos no utilizados.

Puedes usar el Administrador de tareas de Chrome o las grabaciones de memoria de Rutas para detectar elementos no utilizados frecuentemente. colecciones. En el Administrador de tareas, la memoria o la memoria de JavaScript aumentan y disminuyen con frecuencia valores representan recolecciones frecuentes de elementos no utilizados. En las grabaciones de Rutas, aumentan y disminuyen con frecuencia Los gráficos del montón de JS o del recuento de nodos indican recolecciones frecuentes de elementos no utilizados.

Cuando hayas identificado el problema, puedes usar la grabación de la línea de tiempo de asignación para descubrir se asigna la memoria y qué funciones causan las asignaciones.