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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
|
---
title: Arvóre de Chamada
slug: Tools/Performance/Call_Tree
tags:
- Desempenho
- JavaScript
- memoria
translation_of: Tools/Performance/Call_Tree
original_slug: Tools/Desempenho/Arvore_de_Chamada
---
<div>{{ToolsSidebar}}</div><div class="summary">
<p>A '<strong>Árvore de Chamada</strong>' (Call Tree) diz-lhe quais as funções de JavaScript que o navegador gastou mais tempo. Ao analisar os resultados, pode encontrar estrangulamentos no seu código - locais onde o navegador está a gastar uma quantidade desproporcionalmente grande de tempo.</p>
<p>Estes estrangulamentos são locais onde quaisquer otimizações que pode fazer irão ter um grande impacto.</p>
</div>
<p>The Call Tree is a sampling profiler. It periodically samples the state of the JavaScript engine and records the stack for the code executing at the time. Statistically, the number of samples taken in which we were executing a particular function corresponds to the amount of time the browser spent executing it.</p>
<div class="note">
<p>In this article, we'll use the output of a simple program as an example. If you want to get the program to experiment with your profile, you can find it <a href="https://github.com/mdn/performance-scenarios/blob/gh-pages/js-call-tree-1/">here</a>. You can find the specific profile we discuss <a href="https://github.com/mdn/performance-scenarios/blob/gh-pages/js-call-tree-1/profile/call-tree.json">here</a> - just import it to the performance tool to follow along.</p>
<p>There's a short page describing the structure of this program <a href="https://developer.mozilla.org/en-US/docs/Tools/Performance/Examples/Sorting_algorithms_comparison">here</a>.</p>
<p>Note that we use the same program - the same profile, in fact - in the documentation page for the <a href="/en-US/docs/Tools/Performance/Flame_Chart">Flame Chart</a>.</p>
</div>
<p>The screenshot below shows the output of a program that compares three sorting algorithms - bubble sort, selection sort, and quicksort. To do this, it generates some arrays filled with random integers and sorts them using each algorithm in turn.</p>
<p>We've <a href="/en-US/docs/Tools/Performance/UI_Tour#Zooming_in">zoomed</a> into the part of the recording that shows a long JavaScript marker:</p>
<p><img alt="" src="https://mdn.mozillademos.org/files/10981/perf-call-tree.png" style="display: block; height: 574px; margin-left: auto; margin-right: auto; width: 1052px;"></p>
<p>The Call Tree presents the results in a table. Each row represents a function in which at least one sample was taken, and the rows are ordered by the number of samples taken while in that function, highest to lowest.</p>
<p><em>Samples</em> is the number of samples that were taken when we were executing this particular function.</p>
<p><em>Self Cost</em> is that number as a percentage of the total number of samples in the selected portion of the recording.</p>
<p><em>Self Time</em> is that number translated into milliseconds, based on the total amount of time covered by the selected portion of the recording.</p>
<p>In the current version of the Call Tree, these are the most important columns. Functions with a relatively high <em>Self Cost</em> are good candidates for optimization, either because they take a long time to run, or because they are called very often.</p>
<p>This screenshot tells us something we probably already knew: Bubble sort is a very inefficient algorithm. We have about six times as many samples in bubble sort as in selection sort, and 13 times as many as in quicksort.</p>
<h2 id="Mover-se_na_árvore_de_chamada">Mover-se na árvore de chamada</h2>
<p>Next to each function name is a disclosure arrow: Click that, and you can see the path back up the call tree, from the function in which the sample was taken, to the root. For example, we can expand the entry for <code>bubbleSort()</code>:</p>
<p><img alt="" src="https://mdn.mozillademos.org/files/10983/perf-call-tree-expanded-bubblesort.png" style="display: block; height: 512px; margin-left: auto; margin-right: auto; width: 1054px;"></p>
<p>So we can see the call graph is like this:</p>
<pre>sortAll()
-> sort()
-> bubbleSort()</pre>
<p>Note also that <em>Self Cost</em> for <code>sort()</code> here is 1.45%, and note that this is the same as for the separate entry for <code>sort()</code> later in the list. This is telling us that some samples were taken in <code>sort()</code> itself, rather than in the functions it calls.</p>
<p>Sometimes there's more than one path back from an entry to the top level. Let's expand the entry for <code>swap()</code>:</p>
<p><img alt="" src="https://mdn.mozillademos.org/files/10985/perf-call-tree-expanded-sawp.png" style="display: block; height: 636px; margin-left: auto; margin-right: auto; width: 1052px;"></p>
<p>There were 253 samples taken inside <code>swap()</code>. But <code>swap()</code> was reached by two different paths: both <code>bubbleSort()</code> and <code>selectionSort()</code> use it. We can also see that 252 of the 253 samples in <code>swap() </code>were taken in the <code>bubbleSort()</code> branch, and only one in the <code>selectionSort()</code> branch.</p>
<p>This result means that bubble sort is even less efficient than we had thought! It can shoulder the blame for another 252 samples, or almost another 10% of the total cost.</p>
<p>With this kind of digging, we can figure out the whole call graph, with associated sample count:</p>
<pre>sortAll() // 8
-> sort() // 37
-> bubbleSort() // 1345
-> swap() // 252
-> selectionSort() // 190
-> swap() // 1
-> quickSort() // 103
-> partition() // 12</pre>
<h2 id="Dados_da_plataforma">Dados da plataforma</h2>
<p>You'll also see some rows labeled <em>Gecko</em>, <em>Input & Events</em>, and so on. These represent internal browser calls.</p>
<p>This can be useful information too. If your site is making the browser work hard, this might not show up as samples recorded in your code, but it is still your problem.</p>
<p>In our example, there are 679 samples assigned to <em>Gecko </em>- the second-largest group after <code>bubbleSort()</code>. Let's expand that:</p>
<p><img alt="" src="https://mdn.mozillademos.org/files/10987/perf-call-tree-expanded-gecko.png" style="display: block; height: 478px; margin-left: auto; margin-right: auto; width: 1050px;"></p>
<p>This result is telling us that 614 of those samples, or about 20% of the total cost, are coming from our <code>sort()</code> call. If we look at the code for <code>sort()</code>, it should be fairly obvious that the high platform data cost is coming from repeated calls to <code>console.log()</code>:</p>
<pre class="brush: js">function sort(unsorted) {
console.log(bubbleSort(unsorted));
console.log(selectionSort(unsorted));
console.log(quickSort(unsorted));
}</pre>
<p>It would certainly be worthwhile considering more efficient ways of implementing this.</p>
<p>One thing to be aware of here is that idle time is classified as <em>Gecko</em>, so parts of your profile where your JavaScript isn't running will contribute <em>Gecko</em> samples. These aren't relevant to the performance of your site.</p>
<div class="note">
<p>By default, the Call Tree doesn't split platform data out into separate functions, because they add a great deal of noise, and the details are not likely to be useful to people not working on Firefox. If you want to see the details, check "Show Gecko Platform Data" in the <a href="/en-US/docs/Tools/Performance/UI_Tour#Toolbar">Settings</a>.</p>
</div>
<div id="SL_balloon_obj" style="display: block;">
<div class="SL_ImTranslatorLogo" id="SL_button" style="background: rgba(0, 0, 0, 0) repeat scroll 0% 0%; opacity: 1; display: none; left: -8px; top: -25px;"> </div>
<div id="SL_shadow_translation_result2" style="display: none;"> </div>
<div id="SL_shadow_translator" style="display: none;">
<div id="SL_planshet">
<div id="SL_arrow_up" style="background: rgba(0, 0, 0, 0) repeat scroll 0% 0%;"> </div>
<div id="SL_Bproviders">
<div class="SL_BL_LABLE_ON" id="SL_P0" title="Google">G</div>
<div class="SL_BL_LABLE_ON" id="SL_P1" title="Microsoft">M</div>
<div class="SL_BL_LABLE_ON" id="SL_P2" title="Translator">T</div>
</div>
<div id="SL_alert_bbl" style="display: none;">
<div id="SLHKclose" style="background: rgba(0, 0, 0, 0) repeat scroll 0% 0%;"> </div>
<div id="SL_alert_cont"> </div>
</div>
<div id="SL_TB">
<table id="SL_tables">
<tbody>
<tr>
<td class="SL_td"><input></td>
<td class="SL_td"><select><option value="auto">Detectar idioma</option><option value="af">Africâner</option><option value="sq">Albanês</option><option value="de">Alemão</option><option value="ar">Arabe</option><option value="hy">Armênio</option><option value="az">Azerbaijano</option><option value="eu">Basco</option><option value="bn">Bengali</option><option value="be">Bielo-russo</option><option value="my">Birmanês</option><option value="bs">Bósnio</option><option value="bg">Búlgaro</option><option value="ca">Catalão</option><option value="kk">Cazaque</option><option value="ceb">Cebuano</option><option value="ny">Chichewa</option><option value="zh-CN">Chinês (Simp)</option><option value="zh-TW">Chinês (Trad)</option><option value="si">Cingalês</option><option value="ko">Coreano</option><option value="ht">Crioulo haitiano</option><option value="hr">Croata</option><option value="da">Dinamarquês</option><option value="sk">Eslovaco</option><option value="sl">Esloveno</option><option value="es">Espanhol</option><option value="eo">Esperanto</option><option value="et">Estoniano</option><option value="fi">Finlandês</option><option value="fr">Francês</option><option value="gl">Galego</option><option value="cy">Galês</option><option value="ka">Georgiano</option><option value="el">Grego</option><option value="gu">Gujarati</option><option value="ha">Hauça</option><option value="iw">Hebraico</option><option value="hi">Hindi</option><option value="hmn">Hmong</option><option value="nl">Holandês</option><option value="hu">Húngaro</option><option value="ig">Igbo</option><option value="id">Indonésio</option><option value="en">Inglês</option><option value="yo">Ioruba</option><option value="ga">Irlandês</option><option value="is">Islandês</option><option value="it">Italiano</option><option value="ja">Japonês</option><option value="jw">Javanês</option><option value="kn">Kannada</option><option value="km">Khmer</option><option value="lo">Laosiano</option><option value="la">Latim</option><option value="lv">Letão</option><option value="lt">Lituano</option><option value="mk">Macedônico</option><option value="ml">Malaiala</option><option value="ms">Malaio</option><option value="mg">Malgaxe</option><option value="mt">Maltês</option><option value="mi">Maori</option><option value="mr">Marathi</option><option value="mn">Mongol</option><option value="ne">Nepalês</option><option value="no">Norueguês</option><option value="fa">Persa</option><option value="pl">Polonês</option><option value="pt">Português</option><option value="pa">Punjabi</option><option value="ro">Romeno</option><option value="ru">Russo</option><option value="sr">Sérvio</option><option value="st">Sesotho</option><option value="so">Somália</option><option value="sw">Suaíli</option><option value="su">Sudanês</option><option value="sv">Sueco</option><option value="tg">Tadjique</option><option value="tl">Tagalo</option><option value="th">Tailandês</option><option value="ta">Tâmil</option><option value="cs">Tcheco</option><option value="te">Telugo</option><option value="tr">Turco</option><option value="uk">Ucraniano</option><option value="ur">Urdu</option><option value="uz">Uzbeque</option><option value="vi">Vietnamita</option><option value="yi">Yiddish</option><option value="zu">Zulu</option></select></td>
<td class="SL_td">
<div id="SL_switch_b" style="background: rgba(0, 0, 0, 0) repeat scroll 0% 0%;" title="Alternar Idiomas"> </div>
</td>
<td class="SL_td"><select><option value="af">Africâner</option><option value="sq">Albanês</option><option value="de">Alemão</option><option value="ar">Arabe</option><option value="hy">Armênio</option><option value="az">Azerbaijano</option><option value="eu">Basco</option><option value="bn">Bengali</option><option value="be">Bielo-russo</option><option value="my">Birmanês</option><option value="bs">Bósnio</option><option value="bg">Búlgaro</option><option value="ca">Catalão</option><option value="kk">Cazaque</option><option value="ceb">Cebuano</option><option value="ny">Chichewa</option><option value="zh-CN">Chinês (Simp)</option><option value="zh-TW">Chinês (Trad)</option><option value="si">Cingalês</option><option value="ko">Coreano</option><option value="ht">Crioulo haitiano</option><option value="hr">Croata</option><option value="da">Dinamarquês</option><option value="sk">Eslovaco</option><option value="sl">Esloveno</option><option value="es">Espanhol</option><option value="eo">Esperanto</option><option value="et">Estoniano</option><option value="fi">Finlandês</option><option value="fr">Francês</option><option value="gl">Galego</option><option value="cy">Galês</option><option value="ka">Georgiano</option><option value="el">Grego</option><option value="gu">Gujarati</option><option value="ha">Hauça</option><option value="iw">Hebraico</option><option value="hi">Hindi</option><option value="hmn">Hmong</option><option value="nl">Holandês</option><option value="hu">Húngaro</option><option value="ig">Igbo</option><option value="id">Indonésio</option><option selected value="en">Inglês</option><option value="yo">Ioruba</option><option value="ga">Irlandês</option><option value="is">Islandês</option><option value="it">Italiano</option><option value="ja">Japonês</option><option value="jw">Javanês</option><option value="kn">Kannada</option><option value="km">Khmer</option><option value="lo">Laosiano</option><option value="la">Latim</option><option value="lv">Letão</option><option value="lt">Lituano</option><option value="mk">Macedônico</option><option value="ml">Malaiala</option><option value="ms">Malaio</option><option value="mg">Malgaxe</option><option value="mt">Maltês</option><option value="mi">Maori</option><option value="mr">Marathi</option><option value="mn">Mongol</option><option value="ne">Nepalês</option><option value="no">Norueguês</option><option value="fa">Persa</option><option value="pl">Polonês</option><option value="pt">Português</option><option value="pa">Punjabi</option><option value="ro">Romeno</option><option value="ru">Russo</option><option value="sr">Sérvio</option><option value="st">Sesotho</option><option value="so">Somália</option><option value="sw">Suaíli</option><option value="su">Sudanês</option><option value="sv">Sueco</option><option value="tg">Tadjique</option><option value="tl">Tagalo</option><option value="th">Tailandês</option><option value="ta">Tâmil</option><option value="cs">Tcheco</option><option value="te">Telugo</option><option value="tr">Turco</option><option value="uk">Ucraniano</option><option value="ur">Urdu</option><option value="uz">Uzbeque</option><option value="vi">Vietnamita</option><option value="yi">Yiddish</option><option value="zu">Zulu</option></select></td>
<td class="SL_td">
<div id="SL_TTS_voice" style="background: rgba(0, 0, 0, 0) repeat scroll 0% 0%;" title="Ouça"> </div>
</td>
<td class="SL_td">
<div class="SL_copy" id="SL_copy" style="background: rgba(0, 0, 0, 0) repeat scroll 0% 0%;" title="Copiar"> </div>
</td>
<td class="SL_td">
<div id="SL_bbl_font_patch"> </div>
<div class="SL_bbl_font" id="SL_bbl_font" style="background: rgba(0, 0, 0, 0) repeat scroll 0% 0%;" title="Tamanho da fonte"> </div>
</td>
<td class="SL_td">
<div id="SL_bbl_help" style="background: rgba(0, 0, 0, 0) repeat scroll 0% 0%;" title="Ajuda"> </div>
</td>
<td class="SL_td">
<div class="SL_pin_off" id="SL_pin" style="background: rgba(0, 0, 0, 0) repeat scroll 0% 0%;" title="Fixar a janela de pop-up"> </div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div id="SL_shadow_translation_result" style=""> </div>
<div class="SL_loading" id="SL_loading" style="background: rgba(0, 0, 0, 0) repeat scroll 0% 0%;"> </div>
<div id="SL_player2"> </div>
<div id="SL_alert100">A função de fala é limitada a 200 caracteres</div>
<div id="SL_Balloon_options" style="background: rgb(255, 255, 255) repeat scroll 0% 0%;">
<div id="SL_arrow_down" style="background: rgba(0, 0, 0, 0) repeat scroll 0% 0%;"> </div>
<table id="SL_tbl_opt" style="width: 100%;">
<tbody>
<tr>
<td><input></td>
<td>
<div id="SL_BBL_IMG" style="background: rgba(0, 0, 0, 0) repeat scroll 0% 0%;" title="Mostrar o botão do ImTranslator 3 segundos"> </div>
</td>
<td><a class="SL_options" title="Mostrar opções">Opções</a> : <a class="SL_options" title="Histórico de tradução">Histórico</a> : <a class="SL_options" title="Comentários">Comentários</a> : <a class="SL_options" href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=GD9D8CPW8HFA2" title="Faça sua contribuição">Donate</a></td>
<td><span id="SL_Balloon_Close" title="Encerrar">Encerrar</span></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
|