1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
|
---
title: JavaScript Profiler
slug: Tools/Profiler
translation_of: Tools/Performance
translation_of_original: Tools/Profiler
---
<div>
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. </div>
<div>
</div>
<div>
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. </div>
<div>
</div>
<div>
La <a href="/en-US/docs/Tools/DevTools_Window">Caja de herramientas</a> se abrirá, con el Profiler seleccionado.</div>
<div>
</div>
<h2 id="Los_perfiladores_de_muestreo"><a name="sampling-profilers">Los perfiladores de muestreo</a></h2>
<p>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.<br>
<br>
<a name="profiling-example">Por ejemplo, considere un programa como este:</a></p>
<pre class="brush: js">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();</pre>
<p>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. </p>
<p>Todos están tomadas desde el interior <code>doSomething()</code>, pero los otros dos se encuentran dentro de la función <code>logTheValue()</code> llamado por <code>doSomething()</code>. Así que el perfil consistiría en tres seguimientos de pila, como este:</p>
<pre>Sample A: doSomething()
Sample B: doSomething() > logTheValue()
Sample C: doSomething() > logTheValue()</pre>
<p>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 <code>logTheValue()</code> es el cuello de botella en nuestro código.</p>
<h2 id="Creación_de_un_perfil">Creación de un perfil</h2>
<p>Haga clic en el botón del cronómetro (<em>stopwatch</em><span style="font-size: 14px; line-height: 1.5;">) 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:</span></p>
<p style="text-align: center;"><img alt="" src="https://mdn.mozillademos.org/files/5977/Screen%20Shot%202013-08-26%20at%2010.35.47%20AM.png"></p>
<p>Una vez que haya hecho clic en "Stop", el nuevo perfil se abrirá de forma automática:</p>
<p><img alt="" src="https://mdn.mozillademos.org/files/5981/Screen%20Shot%202013-08-26%20at%2011.07.18%20AM.png" style="display: block; margin-left: auto; margin-right: auto;"></p>
<p>Este panel está dividido en dos partes:</p>
<ul>
<li>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 (<em>stopwatch</em>) le permite grabar un nuevo perfil, mientras que el botón Importar (<em>Import</em>) ... 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). </li>
<li>El lado derecho muestra el perfil actualmente cargado.</li>
</ul>
<h2 id="Analyzing_a_profile">Analyzing a profile</h2>
<p>The profile is split into two parts:</p>
<ul>
<li>the <a href="#profile-timeline" title="#profile-timeline">profile timeline</a></li>
<li>the <a href="#profile-details" title="#profile-details">profile details</a></li>
</ul>
<h3 id="Profile_timeline"><a name="profile-timeline">Profile timeline</a></h3>
<p>The profile timeline occupies the top part of the profile display:</p>
<p><img alt="" src="https://mdn.mozillademos.org/files/5987/timeline" style="display: block; margin-left: auto; margin-right: auto;">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.</p>
<p>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 <a href="/en-US/docs/Web/API/window.requestAnimationFrame" title="/en-US/docs/Web/API/window.requestAnimationFrame">requestAnimationFrame</a> and <a href="/en-US/docs/Web/Guide/Performance/Using_web_workers" title="/en-US/docs/Web/Guide/Performance/Using_web_workers">Workers</a>.</p>
<p>You can examine a specific range within the profile by clicking and dragging inside the timeline:</p>
<p><img alt="" src="https://mdn.mozillademos.org/files/5989/Screen%20Shot%202013-08-26%20at%2011.17.59%20AM.png" style="display: block; margin-left: auto; margin-right: auto;"></p>
<p>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:</p>
<p><br>
<img alt="" src="https://mdn.mozillademos.org/files/5991/Screen%20Shot%202013-08-26%20at%2011.18.03%20AM.png" style="display: block; margin-left: auto; margin-right: auto;"></p>
<h3 id="Profile_details"><a name="profile-details">Profile details</a></h3>
<p>The profile details occupy the bottom part of the profile display:</p>
<p><img alt="" src="https://mdn.mozillademos.org/files/5993/profiler-details-highligted.png" style="display: block; margin-left: auto; margin-right: auto;">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.</p>
<p><img alt="" src="https://mdn.mozillademos.org/files/5995/Screen%20Shot%202013-08-26%20at%2011.22.10%20AM.png"></p>
<p><strong>Running time</strong> shows the total number of samples in which this function appeared<a href="#footnote-1"><sup>1</sup></a>, 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 <code>detectImage()</code> function.</p>
<p><strong>Self</strong> 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 <a href="#profiling-example" title="#profiling-example">simple example</a> above, <code>doSomething()</code> would have a <strong>Running time</strong> of 3 (samples A, B, and C), but a <strong>Self</strong> value of 1 (sample A).</p>
<p>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.</p>
<h3 id="Expanding_the_call_tree">Expanding the call tree</h3>
<p>In a given row, if there are any samples taken while we were in a function called by this function (that is, if <strong>Running Time</strong> is greater than <strong>Self</strong> for a given row) then an arrow appears to the left of the function's name, enabling you to expand the call tree.</p>
<p>In the <a href="#profiling-example" title="#profiling-example">simple example</a> above, the fully-expanded call tree would look like this:</p>
<table class="standard-table">
<tbody>
<tr>
<td style="text-align: center;"><strong>Running Time</strong></td>
<td style="text-align: center;"><strong>Self</strong></td>
<td style="text-align: center;"> </td>
</tr>
<tr>
<td style="text-align: center;">3 100%</td>
<td style="text-align: center;">1</td>
<td style="text-align: center;">doSomething()</td>
</tr>
<tr>
<td style="text-align: center;">2 67%</td>
<td style="text-align: center;">2</td>
<td style="text-align: center;">logTheValue()</td>
</tr>
</tbody>
</table>
<p>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 <code>detectImage()</code> function. But all of them were taken in functions called by <code>detectImage()</code> (the <strong>Self</strong> cell is zero). We can expand the call tree to find out which functions were actually running when most of the samples were taken:</p>
<p><img alt="" src="https://mdn.mozillademos.org/files/5999/bla.png" style="display: block; margin-left: auto; margin-right: auto;"></p>
<p>This tells us that 6 samples were taken when we were actually executing <code>detectAtScale(), </code>12 when we were executing <code>getRect()</code> and so on.</p>
<h2 id="Footnotes">Footnotes</h2>
<ol>
<li><a name="footnote-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 <code>forEach</code> will appear multiple times in the call tree.</a></li>
</ol>
<p> </p>
|