JavaScript Profiler

Esta traducción está incompleta. Por favor, ayuda a traducir este artículo del inglés.

Utilice la herramienta de perfiles para encontrar los cuellos de botella en el código JavaScript. El Profiler muestras periódicamente la pila actual de llamadas JavaScript y compila información sobre las muestras. 
 
Puede iniciar el Analizador seleccionando "Profiler" en el menú "Web Developer". Usted encontrará en el menú "Web Developer" en el menú "Herramientas" en Linux y OS X, y directamente bajo el menú "Firefox" en Windows. 
 
La Caja de herramientas se abrirá, con el Profiler seleccionado.
 

Los perfiladores de muestreo

El perfilador de JavaScript es un generador de perfiles de muestreo. Esto significa que las muestras periódicamente el estado del motor de JavaScript, y registra la pila para el código que se ejecuta en el momento de tomar la muestra. Estadísticamente, el número de muestras tomadas en la que estábamos ejecutando una función particular, corresponde a la cantidad de tiempo que el navegador está gastando ejecutarlo, para que pueda identificar los cuellos de botella en el código.

Por ejemplo, considere un programa como este:

function doSomething() {
  var x = getTheValue();
  x = x + 1;                   // -> sample A
  logTheValue(x);
}

function getTheValue() {
  return 5;
}

function logTheValue(x) {
 console.log(x);               // -> sample B, sample C
}

doSomething();

Supongamos que ejecutar este programa con el perfilador activo, y en el tiempo que se tarda en ejecutar, el perfilador toma de tres muestras, como se indica en los comentarios en línea de arriba. 

Todos están tomadas desde el interior doSomething(), pero los otros dos se encuentran dentro de la función logTheValue() llamado por doSomething(). Así que el perfil consistiría en tres seguimientos de pila, como este:

Sample A: doSomething()
Sample B: doSomething() > logTheValue()
Sample C: doSomething() > logTheValue()

Esto, obviamente, no hay suficientes datos para que nos digan nada, pero con mucho más muestras de que podría ser capaz de concluir que logTheValue() es el cuello de botella en nuestro código.

Creación de un perfil

Haga clic en el botón del cronómetro (stopwatch) en el Profiler para iniciar muestras de grabación. Cuando Profiler está grabando, se resaltará el botón del cronómetro. Haga clic en él de nuevo para detener la grabación y guardar el nuevo perfil:

Una vez que haya hecho clic en "Stop", el nuevo perfil se abrirá de forma automática:

Este panel está dividido en dos partes:

  • El lado izquierdo muestra todos los perfiles que ha capturado y le permite cargar cada uno. Justo por encima de esto hay dos botones: el botón del cronómetro (stopwatch) le permite grabar un nuevo perfil, mientras que el botón Importar (Import) ... permite importar los datos guardados anteriormente. Cuando se selecciona el perfil, puede guardar sus datos como un archivo JSON haciendo clic en el botón Guardar (Save). 
  • El lado derecho muestra el perfil actualmente cargado.

Analyzing a profile

The profile is split into two parts:

Profile timeline

The profile timeline occupies the top part of the profile display:

The horizontal axis is time, and the vertical axis is call stack size at that sample. Call stack represents the amount of active functions at the time when the sample was taken.

Red samples along the chart indicate the browser was unresponsive during that time, and a user would notice pauses in animations and responsiveness. If a profile has red samples, consider breaking this code up into several events, and look into using requestAnimationFrame and Workers.

You can examine a specific range within the profile by clicking and dragging inside the timeline:

A new button then appears above the timeline labeled "Sample Range [AAA, BBB]". Clicking that button zooms the profile, and the details view underneath it, to that timeslice:


Profile details

The profile details occupy the bottom part of the profile display:

When you first open a new sample, the sample pane contains a single row labeled "(total)", as in the screenshot above. If you click the arrow next to "(total)", you'll see a list of all the top-level functions which appear in a sample.

Running time shows the total number of samples in which this function appeared1, followed by the percentage of all samples in the profile in which this function appeared. The first row above shows that there were 2021 samples in the entire profile, and the second row shows that 1914, or 94.7%, of them were inside the detectImage() function.

Self shows the number of samples in which the sample was taken while executing this function itself, and not a function it was calling. In the simple example above, doSomething() would have a Running time of 3 (samples A, B, and C), but a Self value of 1 (sample A).

The third column gives the name of the function along with the filename and line number (for local functions) or basename and domain name (for remote functions). Functions in gray are built-in browser functions: functions in black represent JavaScript loaded by the page. If you hover the mouse over a row you'll see an arrow to the right of the function's identifier: click the arrow and you'll be taken to the function source.

Expanding the call tree

In a given row, if there are any samples taken while we were in a function called by this function (that is, if Running Time is greater than Self for a given row) then an arrow appears to the left of the function's name, enabling you to expand the call tree.

In the simple example above, the fully-expanded call tree would look like this:

Running Time Self  
3            100% 1 doSomething()
2              67% 2 logTheValue()

To take a more realistic example: in the screenshot below, looking at the second row we can see that 1914 samples were taken inside the detectImage() function. But all of them were taken in functions called by detectImage() (the Self cell is zero). We can expand the call tree to find out which functions were actually running when most of the samples were taken:

This tells us that 6 samples were taken when we were actually executing detectAtScale(), 12 when we were executing getRect() and so on.

Footnotes

  1. If the function is called multiple times from different sources, it will be represented multiple times in the Profiler output. So generic functions like forEach will appear multiple times in the call tree.

 

Etiquetas y colaboradores del documento

 Colaboradores en esta página: MrDaza
 Última actualización por: MrDaza,