aboutsummaryrefslogtreecommitdiff
path: root/files/pt-pt/tools/performance/waterfall/index.html
blob: dd58c2d7d53740f5bdbb6eb6bd08510ca4b35a58 (plain)
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
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
---
title: Cascata
slug: Tools/Performance/Waterfall
translation_of: Tools/Performance/Waterfall
original_slug: Tools/Desempenho/Cascata
---
<div>{{ToolsSidebar}}</div><div class="summary">
<p>A '<strong>Cascata</strong>' (Waterfall) mostra-lhe várias coisas que o navegador está a fazer na medida em que este excecuta o seu site ou aplicação. É baseado na ideia de que as coisas que o navegador faz quando executa um site pode ser dividido em vários tipos - executar JavaScript, atualizar a disposição, etc... - e que em qualquer ponto no tempo, o navegador está a fazer essas coisas.</p>

<p>Assim, se vir um sinal de um problema de desempenho - uma quebra na <em>frame rate</em>, por exemplo - pode ir para a 'Cascata' para ver o que o navegador estava a fazer nesse ponto da gravação.</p>
</div>

<p><img alt="" src="https://mdn.mozillademos.org/files/10951/perf-waterfall.png" style="display: block; height: 568px; margin-left: auto; margin-right: auto; width: 972px;"></p>

<p>Along the X-axis is time. Recorded operations, called markers, are shown as horizontal bars, laid out in a waterfall to reflect the serial nature of the browser's execution.</p>

<p>When a marker is selected you'll see more information about it in a sidebar on the right. This includes the marker's duration and some more information that's specific to the <a href="/en-US/docs/Tools/Performance/Waterfall#Markers">marker type</a>.</p>

<h2 id="Marcadores"><a id="timeline-color-coding" name="timeline-color-coding"></a>Marcadores</h2>

<p>The markers for operations are color-coded and labeled. The following operations are recorded:</p>

<table class="fullwidth-table standard-table">
 <thead>
  <tr>
   <th scope="col" style="width: 20%;">Nome e descrição</th>
   <th scope="col">Cor</th>
   <th scope="col">Informação detalhada</th>
  </tr>
 </thead>
 <tbody>
  <tr>
   <td style="width: 40%;">
    <p><a id="DOM_Event_Marker" name="DOM_Event_Marker"><strong>DOM Event</strong></a></p>

    <p>JavaScript code that's executed in response to a DOM event.</p>
   </td>
   <td><img alt="" src="https://mdn.mozillademos.org/files/10703/orange.png" style="height: 21px; width: 60px;"></td>
   <td style="width: 45%;">
    <dl>
     <dt>Event Type</dt>
     <dd>For example, "click" or "message".</dd>
    </dl>

    <dl>
     <dt>Event Phase</dt>
     <dd>For example, "Target" or "Capture".</dd>
    </dl>
   </td>
  </tr>
  <tr>
   <td>
    <p>JavaScript functions executed in the page are labeled with the reason the function was called:</p>

    <p><strong>Script Tag<br>
     setInterval<br>
     setTimeout<br>
     requestAnimationFrame<br>
     Promise Callback<br>
     Promise Init<br>
     Worker<br>
     JavaScript URI<br>
     Event Handler</strong></p>
   </td>
   <td><img alt="" src="https://mdn.mozillademos.org/files/10703/orange.png" style="height: 21px; width: 60px;"></td>
   <td>
    <dl>
     <dt>Stack</dt>
     <dd>Call stack, with links to functions.</dd>
    </dl>
   </td>
  </tr>
  <tr>
   <td>
    <p><strong>Analisar HTML</strong></p>

    <p>Time spent parsing the page's HTML.</p>
   </td>
   <td><img alt="" src="https://mdn.mozillademos.org/files/10703/orange.png" style="height: 21px; width: 60px;"></td>
   <td>
    <dl>
     <dt>Stack</dt>
     <dd>Call stack, with links to functions.</dd>
    </dl>
   </td>
  </tr>
  <tr>
   <td>
    <p><strong>Analisar XML</strong></p>

    <p>Time spent parsing the page's XML.</p>
   </td>
   <td><img alt="" src="https://mdn.mozillademos.org/files/10703/orange.png" style="height: 21px; width: 60px;"></td>
   <td>
    <dl>
     <dt>Stack</dt>
     <dd>Call stack, with links to functions.</dd>
    </dl>
   </td>
  </tr>
  <tr>
   <td>
    <p><strong>Recalcular Estilo</strong></p>

    <p>Calculating the computed styles that apply to page elements.</p>
   </td>
   <td><img alt="" src="https://mdn.mozillademos.org/files/10707/purple.png" style="height: 21px; width: 60px;"></td>
   <td>
    <dl>
     <dt>Restyle Hint</dt>
     <dd>A string indicating what kind of restyling is needed. The hint may be any of:<br>
     Self<br>
     Subtree<br>
     LaterSiblings<br>
     CSSTransitions<br>
     CSSAnimations<br>
     SVGAttrAnimations<br>
     StyleAttribute<br>
     StyleAttribute_Animations<br>
     Force<br>
     ForceDescendants</dd>
    </dl>
   </td>
  </tr>
  <tr>
   <td>
    <p><strong>Disposição (Layout)</strong></p>

    <p>Calculating the position and size of page elements. This operation is sometimes called "reflow".</p>
   </td>
   <td><img alt="" src="https://mdn.mozillademos.org/files/10707/purple.png" style="height: 21px; width: 60px;"></td>
   <td> </td>
  </tr>
  <tr>
   <td>
    <p><strong>Pintura</strong></p>

    <p>Desenhar píxeis para o ecrã.</p>
   </td>
   <td><img alt="" src="https://mdn.mozillademos.org/files/10705/green.png" style="height: 21px; width: 60px;"></td>
   <td> </td>
  </tr>
  <tr>
   <td>
    <p><strong>Coleção de Lixo</strong></p>

    <p><a href="/en-US/docs/Tools/Performance/Waterfall#Garbage_collection">Garbage collection event</a>. Non-incremental GC events are labeled "(Non-incremental)".</p>
   </td>
   <td><img alt="" src="https://mdn.mozillademos.org/files/10709/red.png" style="height: 21px; width: 60px;"></td>
   <td>
    <dl>
     <dt>Motivo</dt>
     <dd>A string the indicating the reason GC was performed.</dd>
     <dt>Motivo Não Incremental</dt>
     <dd>If the GC event was non-incremental, the string indicates the reason non-incremental GC was performed.</dd>
    </dl>

    <div class="geckoVersionNote">
    <p>New in Firefox 46: if the GC event was caused by allocation pressure, a link appears, labeled "Show Allocation Triggers". Click the link to see the allocation profile leading up to this GC event.</p>

    <p>See <a href="/en-US/docs/Tools/Performance/Allocations#Allocations_and_garbage_collection">Allocations and Garbage Collection</a> for more details.</p>
    </div>
   </td>
  </tr>
  <tr>
   <td>
    <p><strong>Ciclo da Coleção</strong></p>

    <p>Reclaiming C++ reference-counted data structures.</p>

    <p>Like garbage collection, but for C++ objects. See <a href="http://blog.kylehuey.com/post/27564411715/cycle-collection">Kyle Huey's blog post about cycle collection</a>.</p>
   </td>
   <td><img alt="" src="https://mdn.mozillademos.org/files/10709/red.png" style="height: 21px; width: 60px;"></td>
   <td>
    <dl>
     <dt>Tipo</dt>
     <dd>Always "Collect".</dd>
    </dl>
   </td>
  </tr>
  <tr>
   <td>
    <p><strong>CC - Reduçãod e Gráfico</strong></p>

    <p>Preparation/pre-optimization for Cycle Collection.</p>
   </td>
   <td><img alt="" src="https://mdn.mozillademos.org/files/10709/red.png" style="height: 21px; width: 60px;"></td>
   <td>
    <dl>
     <dt>Tipo</dt>
     <dd>Always "ForgetSkippable".</dd>
    </dl>
   </td>
  </tr>
  <tr>
   <td>
    <p><strong>Consola</strong></p>

    <p>The period between matching calls to <code>console.time()</code> and <code>console.timeEnd()</code>.</p>
   </td>
   <td><img alt="" src="https://mdn.mozillademos.org/files/10955/gray.png" style="height: 54px; width: 60px;"></td>
   <td>
    <dl>
     <dt>Nome do temporizador</dt>
     <dd>The argument passed to the <code>console</code> functions.</dd>
     <dt>Stack at start</dt>
     <dd>Call stack <code>console.time()</code>, with links to functions.</dd>
     <dt>Stack at End</dt>
     <dd>(New in Firefox 41). Call stack at <code>console.timeEnd()</code>. If this is inside a callback from a <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise">Promise</a></code>, this will also show the <a href="/en-US/docs/Tools/Performance/Waterfall#Async_stack">"Async stack"</a>.</dd>
    </dl>
   </td>
  </tr>
  <tr>
   <td>
    <p><strong>Data/Hora</strong></p>

    <p>A single call to <code><a href="/en-US/docs/Web/API/Console/timeStamp">console.timeStamp()</a></code>.</p>
   </td>
   <td><img alt="" src="https://mdn.mozillademos.org/files/10953/blue.png" style="height: 54px; width: 60px;"></td>
   <td>
    <dl>
     <dt>Etiqueta</dt>
     <dd>The argument passed to <code>timeStamp()</code>.</dd>
    </dl>
   </td>
  </tr>
  <tr>
   <td>
    <p><strong>DOM - Conteúdo Carregado</strong></p>

    <p>The document's <code><a href="/en-US/docs/Web/Events/DOMContentLoaded">DOMContentLoaded</a></code> event.</p>
   </td>
   <td><img alt="" src="https://mdn.mozillademos.org/files/12191/red.png" style="height: 21px; width: 60px;"></td>
   <td> </td>
  </tr>
  <tr>
   <td>
    <p><strong>Carregamento</strong></p>

    <p>The document's <code><a href="/en-US/docs/Web/Events/load">load</a></code> event.</p>
   </td>
   <td><img alt="" src="https://mdn.mozillademos.org/files/12193/blue.png" style="height: 21px; width: 60px;"></td>
   <td> </td>
  </tr>
  <tr>
   <td>
    <p><strong>Worker event in main thread</strong></p>

    <p>Shown when the main thread sends a message to a worker, or receives a message from a worker.</p>
   </td>
   <td><img alt="" src="https://mdn.mozillademos.org/files/12195/orange2.png" style="height: 21px; width: 60px;"></td>
   <td>
    <p>One of:</p>

    <dl>
     <dt>Serialize data on the main thread</dt>
     <dd>The main thread is serializing a message to be sent to the worker.</dd>
     <dt>Deserialize data on the main thread</dt>
     <dd>The main thread is deserializing a message received from the worker.</dd>
    </dl>
   </td>
  </tr>
  <tr>
   <td>
    <p><strong>Worker event in worker thread</strong></p>

    <p>Shown when a worker receives a message from the main thread, or sends a message to the main thread.</p>
   </td>
   <td><img alt="" src="https://mdn.mozillademos.org/files/12197/orange2-hollow.png" style="height: 21px; width: 60px;"></td>
   <td>
    <p>One of:</p>

    <dl>
     <dt>Serialize data in Worker</dt>
     <dd>The worker is serializing a message to be sent to the main thread.</dd>
     <dt>Deserialize data in Worker</dt>
     <dd>The worker is deserializing a message received from the main thread.</dd>
    </dl>
   </td>
  </tr>
 </tbody>
</table>

<p>The markers, and their colors, are the same in the Waterfall tool as in the <a href="/en-US/docs/Tools/Performance/UI_Tour#Waterfall_overview">Waterfall overview</a>, making is easy to correlate from one to the other.</p>

<h3 id="Filtrar_marcadores">Filtrar marcadores</h3>

<p>You can control which markers are displayed using a button in the <a href="/en-US/docs/Tools/Performance/UI_Tour#Toolbar">Toolbar</a>:</p>

<p><img alt="" src="https://mdn.mozillademos.org/files/13238/perf-markers.png" style="display: block; height: 694px; margin-left: auto; margin-right: auto; width: 799px;"></p>

<h2 id="Padrões_de_cascata">Padrões de cascata</h2>

<p>Exactly what you'll see in the Waterfall is very dependent on the kind of thing your site is doing: JavaScript-heavy sites will have a lot of orange, while visually dynamic sites will have a lot of purple and green. But there are common patterns which can alert you to possible performance problems.</p>

<h3 id="Renderizar_cascata">Renderizar cascata</h3>

<p>One pattern that you'll often see in the Waterfall view is something like this:</p>

<p><img alt="" src="https://mdn.mozillademos.org/files/10711/perf-timeline-waterfall.png" style="display: block; height: 286px; margin-left: auto; margin-right: auto; width: 727px;"></p>

<p>This is a visualization of the basic algorithm the browser uses to update the page in response to some event:</p>

<ol>
 <li><strong>JavaScript Function Call</strong>: some event - for example, a DOM event - causes some JavaScript in the page to run. The JavaScript changes some of the page's DOM or CSSOM.</li>
 <li><strong>Recalculate Style</strong>: if the browser thinks the computed styles for page elements have changed, it must then recalculate them.</li>
 <li><strong>Layout</strong>: next, the browser uses the computed styles to figure out the position and geometry for the elements. This operation is labeled "layout" but is also sometimes called "reflow".</li>
 <li><strong>Paint</strong>: finally, the browser needs to repaint the elements to the screen. One last step is not shown in this sequence: the page may be split into layers, which are painted independently and then combined in a process called "Composition".</li>
</ol>

<p>This sequence needs to fit into a single frame, since the screen isn't updated until it is complete. It's commonly accepted that 60 frames per second is the rate at which animations will appear smooth. For a rate of 60 frames per second, that gives the browser 16.7 milliseconds to execute the complete flow.</p>

<p>Importantly for responsiveness, the browser doesn't always have to go through every step:</p>

<ul>
 <li><a href="/en-US/docs/Web/Guide/CSS/Using_CSS_animations">CSS animations</a> update the page without having to run any JavaScript.</li>
 <li>Not all CSS property changes cause a reflow. Changing properties that can alter an object's geometry and position, such as <code><a href="/en-US/docs/Web/CSS/width">width</a></code>, <code><a href="/en-US/docs/Web/CSS/display">display</a></code>, <code><a href="/en-US/docs/Web/CSS/font-size">font-size</a></code>, or <code><a href="/en-US/docs/Web/CSS/top">top</a></code>, will cause a reflow. However, changing properties that don't alter geometry or position, such as <code><a href="/en-US/docs/Web/CSS/color">color</a></code> or <code><a href="/en-US/docs/Web/CSS/opacity">opacity</a></code>, will not.</li>
 <li>Not all CSS property changes cause a repaint. In particular, if you animate an element using the <code><a href="/en-US/docs/Web/CSS/transform">transform</a></code> property, the browser will use a separate layer for the transformed element, and doesn't even have to repaint when the element is moved: the new position of the element is handled in composition.</li>
</ul>

<p>The <a href="/en-US/docs/Tools/Performance/Scenarios/Animating_CSS_properties">Animating CSS properties</a> article shows how animating different CSS properties can give different performance outcomes, and how the Waterfall can help signal that.</p>

<h3 id="Bloquear_JavaScript">Bloquear JavaScript</h3>

<p>By default, a site's JavaScript is executed in the same thread that the browser uses for layout updates, repaints, DOM events, and so on. This means that long-running JavaScript functions can cause unresponsiveness (jank): animations may not be smooth, or the site might even freeze.</p>

<p>Using the frame rate tool and the Waterfall together, it's easy to see when long-running JavaScript is causing responsiveness problems. In the screenshot below, we've zoomed in on a JS function that's caused a drop in the frame rate:</p>

<p><img alt="" src="https://mdn.mozillademos.org/files/10973/perf-js-blocking-waterfall.png" style="display: block; height: 432px; margin-left: auto; margin-right: auto; width: 1128px;"></p>

<p>The <a href="/en-US/docs/Tools/Performance/Scenarios/Intensive_JavaScript">Intensive JavaScript</a> article shows how the Waterfall can highlight responsiveness problems caused by long JavaScript functions, and how you can use asynchronous methods to keep the main thread responsive.</p>

<h3 id="Pinturas_dispendiosas">Pinturas dispendiosas</h3>

<p>Some paint effects, such as <code><a href="/en-US/docs/Web/CSS/box-shadow">box-shadow</a></code>, can be expensive, especially if you are applying them in a transition where the browser has to calculate them in every frame. If you're seeing drops in the frame rate, especially during graphically-intensive operations and transitions, check the Waterfall for long green markers.</p>

<h3 id="Coleção_de_lixo">Coleção de lixo</h3>

<p>Red markers in the Waterfall represent garbage collection (GC) events, in which <a href="/en-US/docs/Mozilla/Projects/SpiderMonkey">SpiderMonkey</a> (the JavaScript engine in Firefox) walks the heap looking for memory that's no longer reachable and subsequently releasing it. GC is relevant to performance because while it's running the JavaScript engine must be paused, so your program is suspended and will be completely unresponsive.</p>

<p>To help reduce the length of pauses, SpiderMonkey implements <em>incremental GC</em>: this means that it can perform garbage collection in fairly small increments, letting the program run in between. Sometimes, though, it needs to perform a full non-incremental collection, and the program has to wait for it to finish.</p>

<ul>
</ul>

<p>In trying to avoid GC events, and especially non-incremental GC events, it's wise not to try to optimize for the specific implementation of the JavaScript engine. SpiderMonkey uses a complex set of heuristics to determine when GC is needed, and when non-incremental GC in particular is needed. In general, though:</p>

<ul>
 <li>GC is needed when a lot of memory is being allocated</li>
 <li>non-incremental GC is usually needed when the memory allocation rate is high enough that SpiderMonkey may run out of memory during incremental GC</li>
</ul>

<p>When the Waterfall records a GC marker it indicates:</p>

<ul>
 <li>whether the GC was incremental or not</li>
 <li>the reason the GC was performed</li>
 <li>if the GC was non-incremental, the reason it was non-incremental</li>
 <li>starting in Firefox 46, if the GC event was caused by allocation pressure, a link appears, labeled "Show Allocation Triggers". Click the link to see the allocation profile leading up to this GC event. See <a href="/en-US/docs/Tools/Performance/Allocations#Allocations_and_garbage_collection">Allocations and Garbage Collection</a> for more details.</li>
</ul>

<h2 id="Adicionar_marcadores_com_a_API_da_consola">Adicionar marcadores com a API da consola</h2>

<p>Two markers are directly controlled by <a href="/en-US/docs/Web/API/Console">console API</a> calls: "Console" and "Timestamp".</p>

<h3 id="Marcadores_da_consola">Marcadores da consola</h3>

<p>These enable you to mark a specific section of the recording.</p>

<p>To make a console marker, call <code>console.time()</code> at the start of the section, and <code>console.timeEnd()</code> at the end. These functions take an argument which is used to name the section.</p>

<p>For example, suppose we have code like this:</p>

<pre class="brush: js">var iterations = 70;
var multiplier = 1000000000;

function calculatePrimes() {

  console.time("calculating...");

  var primes = [];
  for (var i = 0; i &lt; iterations; i++) {
    var candidate = i * (multiplier * Math.random());
    var isPrime = true;
    for (var c = 2; c &lt;= Math.sqrt(candidate); ++c) {
      if (candidate % c === 0) {
          // not prime
          isPrime = false;
          break;
       }
    }
    if (isPrime) {
      primes.push(candidate);
    }
  }

  console.timeEnd("calculating...");

  return primes;
}</pre>

<p>The Waterfall's output will look something like this:</p>

<p><img alt="" src="https://mdn.mozillademos.org/files/10967/perf-console-time.png" style="display: block; height: 430px; margin-left: auto; margin-right: auto; width: 1192px;"></p>

<p>The marker is labeled with the argument you passed to <code>console.time()</code>, and when you select the marker, you can see the program stack in the right-hand sidebar.</p>

<h4 id="Async_stack">Async stack</h4>

<p class="geckoVersionNote">New in Firefox 41.</p>

<p>Starting in Firefox 41, the right-hand sidebar will also show the stack at the end of the period: that is, at the point <code>console.timeEnd()</code> was called. If <code>console.timeEnd()</code> was called from the resolution of a <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise">Promise</a></code>, it will also display "(Async: Promise)", under which it will show the "async stack": that is, the call stack at the point the promise was made.</p>

<p>For example, consider code like this:</p>

<pre class="brush: js">var timerButton = document.getElementById("timer");
timerButton.addEventListener("click", handleClick, false);

function handleClick() {
  console.time("timer");
  runTimer(1000).then(timerFinished);
}

function timerFinished() {
  console.timeEnd("timer");
  console.log("ready!");
}

function runTimer(t) {
  return new Promise(function(resolve) {
    setTimeout(resolve, t);
  });
}</pre>

<p>The Waterfall will display a marker for the period between <code>time()</code> and <code>timeEnd()</code>, and if you select it, you'll see the async stack in the sidebar:</p>

<p><img alt="" src="https://mdn.mozillademos.org/files/11179/async-stack.png" style="display: block; height: 378px; margin-left: auto; margin-right: auto; width: 352px;"></p>

<h3 id="Marcadores_de_datahora">Marcadores de data/hora</h3>

<p>Timestamps enable you to mark an instant in the recording.</p>

<p>To make a timestamp marker, call <code><a href="/en-US/docs/Web/API/Console/timeStamp">console.timeStamp()</a></code>. You can pass an argument to label the timestamp.</p>

<p>For example, suppose we adapt the code above to make a timestamp every 10 iterations of the loop, labeled with the iteration number:</p>

<pre class="brush: js">var iterations = 70;
var multiplier = 1000000000;

function calculatePrimes() {
  console.time("calculating...");

  var primes = [];
  for (var i = 0; i &lt; iterations; i++) {

    if (i % 10 == 0) {
      console.timeStamp(i.toString());
    }

    var candidate = i * (multiplier * Math.random());
    var isPrime = true;
    for (var c = 2; c &lt;= Math.sqrt(candidate); ++c) {
      if (candidate % c === 0) {
          // not prime
          isPrime = false;
          break;
       }
    }
    if (isPrime) {
      primes.push(candidate);
    }
  }
  console.timeEnd("calculating...");
  return primes;
}</pre>

<p>In the Waterfall you'll now see something like this:</p>

<p><img alt="" src="https://mdn.mozillademos.org/files/10971/perf-timestamp.png" style="display: block; height: 530px; margin-left: auto; margin-right: auto; width: 1192px;"></p>

<p> </p>

<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: 0; display: block; left: -8px; top: -25px; transition: visibility 2s ease 0s, opacity 2s linear 0s;"> </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&amp;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>