Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 <html> | |
| 2 <!-- | |
| 3 Copyright 2016 the V8 project authors. All rights reserved. Use of this source | |
| 4 code is governed by a BSD-style license that can be found in the LICENSE file. | |
| 5 --> | |
| 6 | |
| 7 <head> | |
| 8 <meta charset="UTF-8"> | |
| 9 <style> | |
| 10 body { | |
| 11 font-family: arial; | |
| 12 } | |
| 13 | |
| 14 table { | |
| 15 display: table; | |
| 16 border-spacing: 0px; | |
| 17 } | |
| 18 | |
| 19 tr { | |
| 20 border-spacing: 0px; | |
| 21 padding: 10px; | |
| 22 } | |
| 23 | |
| 24 td, | |
| 25 th { | |
| 26 padding: 3px 10px 3px 5px; | |
| 27 } | |
| 28 | |
| 29 .inline { | |
| 30 display: inline-block; | |
| 31 vertical-align: top; | |
| 32 } | |
| 33 | |
| 34 h2, | |
| 35 h3 { | |
| 36 margin-bottom: 0px; | |
| 37 } | |
| 38 | |
| 39 .hidden { | |
| 40 display: none; | |
| 41 } | |
| 42 | |
| 43 .view { | |
| 44 display: table; | |
| 45 } | |
| 46 | |
| 47 .column { | |
| 48 display: table-cell; | |
| 49 border-right: 1px black dotted; | |
| 50 min-width: 200px; | |
| 51 } | |
| 52 | |
| 53 .column .header { | |
| 54 padding: 0 10px 0 10px | |
| 55 } | |
| 56 | |
| 57 #column { | |
| 58 display: none; | |
| 59 } | |
| 60 | |
| 61 .list { | |
| 62 width: 100%; | |
| 63 } | |
| 64 | |
| 65 select { | |
| 66 width: 100% | |
| 67 } | |
| 68 | |
| 69 .list tbody { | |
| 70 cursor: pointer; | |
| 71 } | |
| 72 | |
| 73 .list tr:nth-child(even) { | |
| 74 background-color: #EFEFEF; | |
| 75 } | |
| 76 | |
| 77 .list tr:nth-child(even).selected { | |
| 78 background-color: #DDD; | |
| 79 } | |
| 80 | |
| 81 .list tr.child { | |
| 82 display: none; | |
| 83 } | |
| 84 | |
| 85 .list tr.child.visible { | |
| 86 display: table-row; | |
| 87 } | |
| 88 | |
| 89 .list .child .name { | |
| 90 padding-left: 20px; | |
| 91 } | |
| 92 | |
| 93 .list .parent td { | |
| 94 border-top: 1px solid #AAA; | |
| 95 } | |
| 96 | |
| 97 .list .total { | |
| 98 font-weight: bold | |
| 99 } | |
| 100 | |
| 101 .list tr.parent { | |
| 102 background-color: #FFF; | |
| 103 } | |
| 104 | |
| 105 .list tr.parent.selected { | |
| 106 background-color: #DDD; | |
| 107 } | |
| 108 | |
| 109 tr.selected { | |
| 110 background-color: #DDD; | |
| 111 } | |
| 112 | |
| 113 .list .position { | |
| 114 text-align: right; | |
| 115 display: none; | |
| 116 } | |
| 117 | |
| 118 .list div.toggle { | |
| 119 cursor: pointer; | |
| 120 } | |
| 121 | |
| 122 #column_0 .position { | |
| 123 display: table-cell; | |
| 124 } | |
| 125 | |
| 126 #column_0 .name { | |
| 127 display: table-cell; | |
| 128 } | |
| 129 | |
| 130 .list .name { | |
| 131 display: none; | |
| 132 white-space: nowrap; | |
| 133 } | |
| 134 | |
| 135 .value { | |
| 136 text-align: right; | |
| 137 } | |
| 138 | |
| 139 .selectedVersion { | |
| 140 font-weight: bold; | |
| 141 } | |
| 142 | |
| 143 #baseline { | |
| 144 width: auto; | |
| 145 } | |
| 146 | |
| 147 .compareSelector { | |
| 148 padding-bottom: 20px; | |
| 149 } | |
| 150 | |
| 151 .pageDetailTable tbody { | |
| 152 cursor: pointer | |
| 153 } | |
| 154 | |
| 155 #popover { | |
| 156 position: absolute; | |
| 157 transform: translateY(-50%) translateX(40px); | |
| 158 box-shadow: -2px 10px 44px -10px #000; | |
| 159 border-radius: 5px; | |
| 160 z-index: 1; | |
| 161 background-color: #FFF; | |
| 162 display: none; | |
| 163 } | |
| 164 | |
| 165 #popover table { | |
| 166 position: relative; | |
| 167 z-index: 1; | |
| 168 text-align: right; | |
| 169 } | |
| 170 | |
| 171 .popoverArrow { | |
| 172 background-color: #FFF; | |
| 173 position: absolute; | |
| 174 width: 30px; | |
| 175 height: 30px; | |
| 176 transform: translateY(-50%)rotate(45deg); | |
| 177 top: 50%; | |
| 178 left: -10px; | |
| 179 z-index: 0; | |
| 180 } | |
| 181 | |
| 182 #popover .name { | |
| 183 padding: 5px; | |
| 184 font-weight: bold; | |
| 185 text-align: center; | |
| 186 } | |
| 187 | |
| 188 #popover table .compare { | |
| 189 display: none | |
| 190 } | |
| 191 | |
| 192 #popover table.compare .compare { | |
| 193 display: table-cell; | |
| 194 } | |
| 195 </style> | |
| 196 <script> | |
| 197 "use strict" | |
| 198 | |
| 199 // Did anybody say monkeypatching? | |
| 200 if (!NodeList.prototype.forEach) { | |
| 201 NodeList.prototype.forEach = function(func) { | |
| 202 for (var i = 0; i < this.length; i++) { | |
| 203 func(this[i]); | |
| 204 } | |
| 205 } | |
| 206 } | |
| 207 | |
| 208 var versions; | |
| 209 var selectedPage; | |
| 210 var baselineVersion; | |
| 211 var selectedEntry; | |
| 212 | |
| 213 function initialize() { | |
| 214 var original = $("column"); | |
| 215 for (var i = 0; i < versions.length || i < 2; i++) { | |
| 216 // add column | |
| 217 var column = original.cloneNode(true); | |
| 218 column.id = "column_" + i; | |
| 219 // Fill in all versions | |
| 220 var select = column.querySelector(".version"); | |
| 221 select.id = "selectVersion_" + i; | |
| 222 // add all select options | |
| 223 versions.forEach((version) => { | |
| 224 var option = document.createElement("option"); | |
| 225 option.textContent = version.name; | |
| 226 option.version = version; | |
| 227 select.appendChild(option); | |
| 228 }); | |
| 229 // Fill in all page versions | |
| 230 select = column.querySelector(".pageVersion"); | |
| 231 select.id = "select_" + i; | |
| 232 // add all select options | |
| 233 versions.forEach((version) => { | |
| 234 var optgroup = document.createElement("optgroup"); | |
| 235 optgroup.label = version.name; | |
| 236 optgroup.version = version; | |
| 237 version.pages.forEach((page) => { | |
| 238 var option = document.createElement("option"); | |
| 239 option.textContent = page.name; | |
| 240 option.page = page; | |
| 241 optgroup.appendChild(option); | |
| 242 }); | |
| 243 select.appendChild(optgroup); | |
| 244 }); | |
| 245 $("view").appendChild(column); | |
| 246 } | |
| 247 var select = $('baseline'); | |
| 248 removeAllChildren(select); | |
| 249 select.appendChild(document.createElement('option')); | |
| 250 versions.forEach((version) => { | |
| 251 var option = document.createElement("option"); | |
| 252 option.textContent = version.name; | |
| 253 option.version = version; | |
| 254 select.appendChild(option); | |
| 255 }); | |
| 256 $('results').querySelectorAll('#results > .hidden').forEach((node) => { | |
| 257 toggleCssClass(node, 'hidden', false); | |
| 258 }); | |
| 259 } | |
| 260 | |
| 261 function showPage(firstPage) { | |
| 262 selectedPage = firstPage; | |
| 263 selectedPage.sort(); | |
| 264 showPageInColumn(firstPage, 0); | |
| 265 // Show the other versions of this page in the following columns. | |
| 266 var pageVersions = versions.pageVersions(firstPage.name); | |
| 267 var index = 1; | |
| 268 pageVersions.forEach((page) => { | |
| 269 if (page !== firstPage) { | |
| 270 showPageInColumn(page, index); | |
| 271 index++; | |
| 272 } | |
| 273 }); | |
| 274 showImpactList(selectedPage); | |
| 275 } | |
| 276 | |
| 277 function showPageInColumn(page, columnIndex) { | |
| 278 page.sort(); | |
| 279 var showDiff = (baselineVersion === undefined && columnIndex !== 0) || | |
| 280 (baselineVersion !== undefined && page.version !== baselineVersion); | |
| 281 var diffStatus = (td, a, b) => {}; | |
| 282 if (showDiff) { | |
| 283 if (baselineVersion !== undefined) { | |
| 284 diffStatus = (td, a, b) => { | |
| 285 if (a == 0) return; | |
| 286 td.style.color = a < 0 ? '#FF0000' : '#00BB00'; | |
| 287 }; | |
| 288 } else { | |
| 289 diffStatus = (td, a, b) => { | |
| 290 if (a == b) return; | |
| 291 var color; | |
| 292 var ratio = a / b; | |
| 293 if (ratio > 1) { | |
| 294 ratio = Math.min(Math.round((ratio - 1) * 255 * 10), 200); | |
| 295 color = '#' + ratio.toString(16) + "0000"; | |
| 296 } else { | |
| 297 ratio = Math.min(Math.round((1 - ratio) * 255 * 10), 200); | |
| 298 color = '#00' + ratio.toString(16) + "00"; | |
| 299 } | |
| 300 td.style.color = color; | |
| 301 } | |
| 302 } | |
| 303 } | |
| 304 | |
| 305 var column = $('column_' + columnIndex); | |
| 306 var select = $('select_' + columnIndex); | |
| 307 // Find the matching option | |
| 308 selectOption(select, (i, option) => { | |
| 309 return option.page == page | |
| 310 }); | |
| 311 var table = column.querySelector("table"); | |
| 312 var oldTbody = table.querySelector('tbody'); | |
| 313 var tbody = document.createElement('tbody'); | |
| 314 var referencePage = selectedPage; | |
| 315 page.forEachSorted(selectedPage, (parentEntry, entry, referenceEntry) => { | |
| 316 // Filter out entries that do not exist in the first column for the defa ult | |
|
nickie
2016/05/06 12:40:48
Comment line too long. Move "default" to next lin
| |
| 317 // view. | |
| 318 if (baselineVersion === undefined && referenceEntry && | |
| 319 referenceEntry.time == 0) { | |
| 320 return; | |
| 321 } | |
| 322 var tr = document.createElement('tr'); | |
| 323 tbody.appendChild(tr); | |
| 324 tr.entry = entry; | |
| 325 tr.parentEntry = parentEntry; | |
| 326 if (!parentEntry) { | |
| 327 tr.className = 'parent' | |
| 328 } else { | |
| 329 tr.className = 'child' | |
| 330 } | |
| 331 // Don't show entries that do not exist on the current page or if we com pare | |
|
nickie
2016/05/06 12:40:48
Same. Move "compare" to next line?
| |
| 332 // against the current page | |
| 333 if (entry !== undefined && page.version !== baselineVersion) { | |
| 334 // If we show a diff, use the baselineVersion as the referenceEntry | |
| 335 if (baselineVersion !== undefined) { | |
| 336 var baselineEntry = baselineVersion.getEntry(entry); | |
| 337 if (baselineEntry !== undefined) referenceEntry = baselineEntry | |
| 338 } | |
| 339 if (!parentEntry) { | |
| 340 var node = td(tr, '<div class="toggle">►</div>', 'position'); | |
| 341 node.firstChild.addEventListener('click', handleToggleGroup); | |
| 342 } else { | |
| 343 td(tr, entry.position == 0 ? '' : entry.position, 'position'); | |
| 344 } | |
| 345 td(tr, entry.name, 'name ' + entry.cssClass()); | |
| 346 diffStatus( | |
| 347 td(tr, ms(entry.time), 'value time'), | |
| 348 entry.time, referenceEntry.time); | |
| 349 diffStatus( | |
| 350 td(tr, percent(entry.timePercent), 'value time'), | |
| 351 entry.time, referenceEntry.time); | |
| 352 diffStatus( | |
| 353 td(tr, count(entry.count), 'value count'), | |
| 354 entry.count, referenceEntry.count); | |
| 355 } else if (baselineVersion !== undefined && referenceEntry && page.versi on !== | |
|
nickie
2016/05/06 12:40:48
Bad formatting. Break after last "&&"?
| |
| 356 baselineVersion) { | |
| 357 // Show comparison of entry that does not exist on the current page. | |
| 358 tr.entry = referenceEntry; | |
| 359 td(tr, '-', 'position'); | |
| 360 td(tr, referenceEntry.name, 'name'); | |
| 361 diffStatus( | |
| 362 td(tr, ms(referenceEntry.time), 'value time'), | |
| 363 referenceEntry.time, 0); | |
| 364 diffStatus( | |
| 365 td(tr, percent(referenceEntry.timePercent), 'value time'), | |
| 366 referenceEntry.timePercent, 0); | |
| 367 diffStatus( | |
| 368 td(tr, count(referenceEntry.count), 'value count'), | |
| 369 referenceEntry.count, 0); | |
| 370 } else { | |
| 371 // Display empty entry / baseline entry | |
| 372 if (entry !== undefined) { | |
| 373 if (!parentEntry) { | |
| 374 var node = td(tr, '<div class="toggle">►</div>', 'position'); | |
| 375 node.firstChild.addEventListener('click', handleToggleGroup); | |
| 376 } else { | |
| 377 td(tr, entry.position == 0 ? '' : entry.position, 'position'); | |
| 378 } | |
| 379 td(tr, entry.name, 'name'); | |
| 380 } else { | |
| 381 td(tr, '-', 'position'); | |
| 382 td(tr, '-', 'name'); | |
| 383 } | |
| 384 td(tr, '-', 'value time'); | |
| 385 td(tr, '-', 'value time'); | |
| 386 td(tr, '-', 'value count'); | |
| 387 } | |
| 388 }); | |
| 389 table.replaceChild(tbody, oldTbody); | |
| 390 var versionSelect = column.querySelector('select.version'); | |
| 391 selectOption(versionSelect, (index, option) => { | |
| 392 return option.version == page.version | |
| 393 }); | |
| 394 } | |
| 395 | |
| 396 function selectEntry(entry, updateSelectedPage) { | |
| 397 if (updateSelectedPage) { | |
| 398 entry = selectedPage.version.getEntry(entry); | |
| 399 } | |
| 400 var rowIndex; | |
| 401 var needsPageSwitch = updateSelectedPage && entry.page != selectedPage; | |
| 402 // If clicked in the detail row change the first column to that page. | |
| 403 if (needsPageSwitch) showPage(entry.page); | |
| 404 var childNodes = $('column_0').querySelector('.list tbody').childNodes; | |
| 405 for (var i = 0; i < childNodes.length; i++) { | |
| 406 if (childNodes[i].entry.name == entry.name) { | |
| 407 rowIndex = i; | |
| 408 break; | |
| 409 } | |
| 410 } | |
| 411 var firstEntry = childNodes[rowIndex].entry; | |
| 412 if (rowIndex) { | |
| 413 if (firstEntry.parent) showGroup(firstEntry.parent); | |
| 414 } | |
| 415 // Deselect all | |
| 416 $('view').querySelectorAll('.list tbody tr').forEach((tr) => { | |
| 417 toggleCssClass(tr, 'selected', false); | |
| 418 }); | |
| 419 // Select the entry row | |
| 420 $('view').querySelectorAll("tbody").forEach((body) => { | |
| 421 var row = body.childNodes[rowIndex]; | |
| 422 if (!row) return; | |
| 423 toggleCssClass(row, 'selected', row.entry && row.entry.name == | |
| 424 firstEntry.name); | |
| 425 }); | |
| 426 if (updateSelectedPage) { | |
| 427 entry = selectedEntry.page.version.getEntry(entry); | |
| 428 } | |
| 429 selectedEntry = entry; | |
| 430 showEntryDetail(entry); | |
| 431 } | |
| 432 | |
| 433 function showEntryDetail(entry) { | |
| 434 var table, tbody, entries; | |
| 435 table = $('detailView').querySelector('.versionDetailTable'); | |
| 436 tbody = document.createElement('tbody'); | |
| 437 if (entry !== undefined) { | |
| 438 $('detailView').querySelector('.versionDetail h3 span').innerHTML = | |
| 439 entry.name; | |
| 440 entries = versions.pageVersions(entry.page.name).map( | |
| 441 (page) => { | |
| 442 return page.get(entry.name) | |
| 443 }); | |
| 444 entries.sort((a, b) => { | |
| 445 return a.time - b.time | |
| 446 }); | |
| 447 entries.forEach((pageEntry) => { | |
| 448 if (pageEntry === undefined) return; | |
| 449 var tr = document.createElement('tr'); | |
| 450 if (pageEntry == entry) tr.className += 'selected'; | |
| 451 tr.entry = pageEntry; | |
| 452 td(tr, pageEntry.page.version.name, 'version'); | |
| 453 td(tr, pageEntry.position, 'value position'); | |
| 454 td(tr, ms(pageEntry.time), 'value time'); | |
| 455 td(tr, percent(pageEntry.timePercent), 'value time'); | |
| 456 td(tr, count(pageEntry.count), 'value count'); | |
| 457 tbody.appendChild(tr); | |
| 458 }); | |
| 459 } | |
| 460 table.replaceChild(tbody, table.querySelector('tbody')); | |
| 461 | |
| 462 table = $('detailView').querySelector('.pageDetailTable'); | |
| 463 tbody = document.createElement('tbody'); | |
| 464 if (entry !== undefined) { | |
| 465 var version = entry.page.version; | |
| 466 $('detailView').querySelector('.pageDetail h3 span').innerHTML = | |
| 467 version.name; | |
| 468 entries = version.pages.map( | |
| 469 (page) => { | |
| 470 return page.get(entry.name) | |
| 471 }); | |
| 472 entries.sort((a, b) => { | |
| 473 return b.timePercent - a.timePercent | |
| 474 }); | |
| 475 entries.forEach((pageEntry) => { | |
| 476 if (pageEntry === undefined) return; | |
| 477 var tr = document.createElement('tr'); | |
| 478 if (pageEntry === entry) tr.className += 'selected'; | |
| 479 tr.entry = pageEntry; | |
| 480 td(tr, pageEntry.page.name, 'name'); | |
| 481 td(tr, pageEntry.position, 'value position'); | |
| 482 td(tr, ms(pageEntry.time), 'value time'); | |
| 483 td(tr, percent(pageEntry.timePercent), 'value time'); | |
| 484 td(tr, count(pageEntry.count), 'value count'); | |
| 485 tbody.appendChild(tr); | |
| 486 }); | |
| 487 // show the total for all pages | |
| 488 var tds = table.querySelectorAll('tfoot td'); | |
| 489 tds[2].innerHTML = ms(entry.getTimeImpact()); | |
| 490 // Only show the percentage total if we are in diff mode: | |
| 491 if (baselineVersion !== undefined) { | |
| 492 tds[3].innerHTML = percent(entry.getTimePercentImpact()); | |
| 493 } else { | |
| 494 tds[3].innerHTML = '' | |
| 495 } | |
| 496 tds[4].innerHTML = count(entry.getCountImpact()); | |
| 497 } | |
| 498 table.replaceChild(tbody, table.querySelector('tbody')); | |
| 499 showImpactList(entry.page); | |
| 500 } | |
| 501 | |
| 502 function showImpactList(page) { | |
| 503 var impactView = $('detailView').querySelector('.impactView'); | |
| 504 impactView.querySelector('h3 span').innerHTML = page.version.name; | |
| 505 | |
| 506 var table = impactView.querySelector('table'); | |
| 507 var tbody = document.createElement('tbody'); | |
| 508 var version = page.version; | |
| 509 var entries = version.allEntries(); | |
| 510 if (selectedEntry !== undefined && selectedEntry.isGroup) { | |
| 511 impactView.querySelector('h3 span').innerHTML += " " + selectedEntry.nam e; | |
|
nickie
2016/05/06 12:40:48
Bad formatting. Break after "+="?
| |
| 512 entries = entries.filter((entry) => { | |
| 513 return entry.name == selectedEntry.name || | |
|
nickie
2016/05/06 12:40:48
"(entry) => { return ... }" can be written as "ent
| |
| 514 (entry.parent && entry.parent.name == selectedEntry.name) | |
| 515 }); | |
| 516 } | |
| 517 entries.sort((a, b) => { | |
| 518 return b.getTimePercentImpact() - a.getTimePercentImpact(); | |
| 519 }); | |
| 520 entries.forEach((entry) => { | |
| 521 var tr = document.createElement('tr'); | |
| 522 tr.entry = entry; | |
| 523 td(tr, entry.name, 'name'); | |
| 524 td(tr, ms(entry.getTimeImpact()), 'value time'); | |
| 525 td(tr, percent(entry.getTimePercentImpact()), 'value time'); | |
| 526 var topPages = entry.getPagesByPercentImpact().slice(0, 2) | |
| 527 .map((each) => { | |
| 528 return each.name + ' (' + percent(each.getEntry(entry).timePercent) + | |
|
nickie
2016/05/06 12:40:48
Bad formatting. You can skip the braces and the "
| |
| 529 ')' | |
| 530 }); | |
| 531 td(tr, topPages.join(', '), 'name'); | |
| 532 tbody.appendChild(tr); | |
| 533 }); | |
| 534 table.replaceChild(tbody, table.querySelector('tbody')); | |
| 535 } | |
| 536 | |
| 537 function showGroup(entry) { | |
| 538 toggleGroup(entry, true); | |
| 539 } | |
| 540 | |
| 541 function toggleGroup(group, show) { | |
| 542 $('view').querySelectorAll(".child").forEach((tr) => { | |
| 543 var entry = tr.parentEntry; | |
| 544 if (!entry) return; | |
| 545 if (entry.name !== group.name) return; | |
| 546 toggleCssClass(tr, 'visible', show); | |
| 547 }); | |
| 548 } | |
| 549 | |
| 550 function showPopover(entry) { | |
| 551 var popover = $('popover'); | |
| 552 popover.querySelector('td.name').innerHTML = entry.name; | |
| 553 popover.querySelector('td.page').innerHTML = entry.page.name; | |
| 554 setPopoverDetail(popover, entry, ''); | |
| 555 popover.querySelector('table').className = ""; | |
| 556 if (baselineVersion !== undefined) { | |
| 557 entry = baselineVersion.getEntry(entry); | |
| 558 if (entry === undefined) return; | |
| 559 setPopoverDetail(popover, entry, '.compare '); | |
| 560 popover.querySelector('table').className = "compare"; | |
| 561 } | |
| 562 } | |
| 563 | |
| 564 function setPopoverDetail(popover, entry, prefix) { | |
| 565 popover.querySelector(prefix + '.version').innerHTML = entry.page.version | |
| 566 .name; | |
| 567 popover.querySelector(prefix + '.time').innerHTML = ms(entry._time); | |
| 568 popover.querySelector(prefix + '.timeVariance').innerHTML = percent(entry | |
| 569 .timeVariancePercent); | |
| 570 popover.querySelector(prefix + '.percent').innerHTML = percent(entry.timeP ercent); | |
|
nickie
2016/05/06 12:40:48
Bad formatting. Break after "="?
| |
| 571 popover.querySelector(prefix + '.percentVariance').innerHTML = percent( | |
| 572 entry.timePercentVariancePercent); | |
| 573 popover.querySelector(prefix + '.count').innerHTML = count(entry._count); | |
| 574 popover.querySelector(prefix + '.countVariance').innerHTML = percent( | |
| 575 entry.timeVariancePercent); | |
| 576 popover.querySelector(prefix + '.timeImpact').innerHTML = ms(entry.getTime Impact()); | |
|
nickie
2016/05/06 12:40:48
Bad formatting. Break after "="?
| |
| 577 popover.querySelector(prefix + '.timePercentImpact').innerHTML = percent( | |
| 578 entry.getTimePercentImpact()); | |
| 579 } | |
| 580 | |
| 581 // ========================================================================= == | |
|
nickie
2016/05/06 12:40:48
Bad formatting. Fewer "="?
| |
| 582 // Helpers | |
| 583 function $(id) { | |
| 584 return document.getElementById(id) | |
| 585 } | |
| 586 | |
| 587 function removeAllChildren(node) { | |
| 588 while (node.firstChild) { | |
| 589 node.removeChild(node.firstChild); | |
| 590 } | |
| 591 } | |
| 592 | |
| 593 function selectOption(select, match) { | |
| 594 var options = select.options; | |
| 595 for (var i = 0; i < options.length; i++) { | |
| 596 if (match(i, options[i])) { | |
| 597 select.selectedIndex = i; | |
| 598 return; | |
| 599 } | |
| 600 } | |
| 601 } | |
| 602 | |
| 603 function td(tr, content, className) { | |
| 604 var td = document.createElement("td"); | |
| 605 td.innerHTML = content; | |
| 606 td.className = className | |
| 607 tr.appendChild(td); | |
| 608 return td | |
| 609 } | |
| 610 | |
| 611 function nodeIndex(node) { | |
| 612 var children = node.parentNode.childNodes, | |
| 613 i = 0; | |
| 614 for (; i < children.length; i++) { | |
| 615 if (children[i] == node) { | |
| 616 return i; | |
| 617 } | |
| 618 } | |
| 619 return -1; | |
| 620 } | |
| 621 | |
| 622 function toggleCssClass(node, cssClass, toggleState) { | |
| 623 var index = -1; | |
| 624 var classes; | |
| 625 if (node.className != undefined) { | |
| 626 classes = node.className.split(' '); | |
| 627 index = classes.indexOf(cssClass); | |
| 628 } | |
| 629 if (index == -1) { | |
| 630 if (toggleState === false) return; | |
| 631 node.className += ' ' + cssClass; | |
| 632 return; | |
| 633 } | |
| 634 if (toggleState === true) return; | |
| 635 classes.splice(index, 1); | |
| 636 node.className = classes.join(' '); | |
| 637 } | |
| 638 | |
| 639 function diffSign(value) { | |
| 640 if (value <= 0) return ''; | |
| 641 if (baselineVersion == undefined) return ''; | |
| 642 return '+'; | |
| 643 } | |
| 644 | |
| 645 function ms(time) { | |
| 646 return diffSign(time) + time.toFixed(1) + 'ms'; | |
| 647 } | |
| 648 | |
| 649 function count(time) { | |
| 650 return diffSign(time) + time.toFixed(0) + '#'; | |
| 651 } | |
| 652 | |
| 653 function percent(time) { | |
| 654 return diffSign(time) + time.toFixed(1) + '%'; | |
| 655 } | |
| 656 // ========================================================================= == | |
|
nickie
2016/05/06 12:40:48
Bad formatting. Fewer "="? Also, insert one blan
| |
| 657 // EventHandlers | |
| 658 function handleLoadFile() { | |
| 659 var files = document.getElementById("uploadInput").files; | |
| 660 var file = files[0]; | |
| 661 var reader = new FileReader(); | |
| 662 | |
| 663 reader.onload = function(evt) { | |
| 664 versions = Versions.fromJSON(JSON.parse(this.result)); | |
| 665 initialize() | |
| 666 showPage(versions.versions[0].pages[0]); | |
| 667 } | |
| 668 reader.readAsText(file); | |
| 669 } | |
| 670 | |
| 671 function handleToggleGroup(event) { | |
| 672 var group = event.target.parentNode.parentNode.entry; | |
| 673 toggleGroup(selectedPage.get(group.name)); | |
| 674 } | |
| 675 | |
| 676 function handleSelectPage(select, event) { | |
| 677 var option = select.options[select.selectedIndex]; | |
| 678 if (select.id == "select_0") { | |
| 679 showPage(option.page); | |
| 680 } else { | |
| 681 var columnIndex = select.id.split('_')[1]; | |
| 682 showPageInColumn(option.page, columnIndex); | |
| 683 } | |
| 684 } | |
| 685 | |
| 686 function handleSelectVersion(select, event) { | |
| 687 var option = select.options[select.selectedIndex]; | |
| 688 var version = option.version; | |
| 689 if (select.id == "selectVersion_0") { | |
| 690 var page = version.get(selectedPage.name); | |
| 691 showPage(page); | |
| 692 } else { | |
| 693 var columnIndex = select.id.split('_')[1]; | |
| 694 var pageSelect = $('select_' + columnIndex); | |
| 695 var page = pageSelect.options[select.selectedIndex].page; | |
| 696 page = version.get(page.name); | |
| 697 showPageInColumn(page, columnIndex); | |
| 698 } | |
| 699 } | |
| 700 | |
| 701 function handleSelectDetailRow(table, event) { | |
| 702 if (event.target.tagName != 'TD') return; | |
| 703 var tr = event.target.parentNode; | |
| 704 if (tr.tagName != 'TR') return; | |
| 705 if (tr.entry === undefined) return; | |
| 706 selectEntry(tr.entry, true); | |
| 707 } | |
| 708 | |
| 709 function handleSelectRow(table, event, fromDetail) { | |
| 710 if (event.target.tagName != 'TD') return; | |
| 711 var tr = event.target.parentNode; | |
| 712 if (tr.tagName != 'TR') return; | |
| 713 if (tr.entry === undefined) return; | |
| 714 selectEntry(tr.entry, false); | |
| 715 } | |
| 716 | |
| 717 function handleSelectBaseline(select, event) { | |
| 718 var option = select.options[select.selectedIndex]; | |
| 719 baselineVersion = option.version | |
| 720 showPage(selectedPage); | |
| 721 selectEntry(selectedEntry, true); | |
| 722 } | |
| 723 | |
| 724 function handleUpdatePopover(event) { | |
| 725 var popover = $('popover'); | |
| 726 popover.style.left = event.pageX + 'px'; | |
| 727 popover.style.top = event.pageY + 'px'; | |
| 728 popover.style.display = event.shiftKey ? 'block' : 'none'; | |
| 729 var target = event.target; | |
| 730 while (target.entry === undefined) { | |
| 731 target = target.parentNode; | |
| 732 if (!target) return; | |
| 733 } | |
| 734 showPopover(target.entry); | |
| 735 } | |
| 736 | |
| 737 // ========================================================================= == | |
|
nickie
2016/05/06 12:40:48
Bad formatting. Fewer "="?
| |
| 738 | |
| 739 class Versions { | |
| 740 constructor() { | |
| 741 this.versions = []; | |
| 742 } | |
| 743 add(version) { | |
| 744 this.versions.push(version) | |
| 745 } | |
| 746 pageVersions(name) { | |
| 747 var result = []; | |
| 748 this.versions.forEach((version) => { | |
| 749 var page = version.get(name); | |
| 750 if (page !== undefined) result.push(page); | |
| 751 }); | |
| 752 return result; | |
| 753 } | |
| 754 get length() { | |
| 755 return this.versions.length | |
| 756 } | |
| 757 get(index) { | |
| 758 return this.versions[index] | |
| 759 }; | |
| 760 forEach(f) { | |
| 761 this.versions.forEach(f); | |
| 762 } | |
| 763 sort() { | |
| 764 this.versions.sort((a, b) => { | |
| 765 if (a.name > b.name) return 1; | |
| 766 if (a.name < b.name) return -1; | |
| 767 return 0 | |
| 768 }) | |
| 769 } | |
| 770 } | |
| 771 Versions.fromJSON = function(json) { | |
| 772 var versions = new Versions(); | |
| 773 for (var version in json) { | |
| 774 versions.add(Version.fromJSON(version, json[version])); | |
| 775 } | |
| 776 versions.sort(); | |
| 777 return versions; | |
| 778 } | |
| 779 | |
| 780 class Version { | |
| 781 constructor(name) { | |
| 782 this.name = name; | |
| 783 this.pages = [] | |
| 784 } | |
| 785 add(page) { | |
| 786 this.pages.push(page); | |
| 787 } | |
| 788 indexOf(name) { | |
| 789 for (var i = 0; i < this.pages.length; i++) { | |
| 790 if (this.pages[i].name == name) return i; | |
| 791 } | |
| 792 return -1; | |
| 793 } | |
| 794 get(name) { | |
| 795 var index = this.indexOf(name); | |
| 796 if (0 <= index) return this.pages[index]; | |
| 797 return undefined | |
| 798 } | |
| 799 get length() { | |
| 800 return this.versions.length | |
| 801 } | |
| 802 getEntry(entry) { | |
| 803 if (entry === undefined) return undefined; | |
| 804 var page = this.get(entry.page.name); | |
| 805 if (page === undefined) return undefined; | |
| 806 return page.get(entry.name); | |
| 807 } | |
| 808 forEachEntry(fun) { | |
| 809 this.pages.forEach((page) => { | |
| 810 page.forEach(fun); | |
| 811 }); | |
| 812 } | |
| 813 allEntries() { | |
| 814 var map = new Map(); | |
| 815 this.forEachEntry((group, entry) => { | |
| 816 if (!map.has(entry.name)) map.set(entry.name, entry); | |
| 817 }); | |
| 818 return Array.from(map.values()); | |
| 819 } | |
| 820 getTotalValue(name, property) { | |
| 821 if (name === undefined) name = this.pages[0].total.name; | |
| 822 var sum = 0; | |
| 823 this.pages.forEach((page) => { | |
| 824 var entry = page.get(name); | |
| 825 if (entry !== undefined) sum += entry[property]; | |
| 826 }); | |
| 827 return sum; | |
| 828 } | |
| 829 getTotalTime(name) { | |
| 830 return this.getTotalValue(name, 'time'); | |
| 831 } | |
| 832 getTotalTimePercent(name) { | |
| 833 return this.getTotalValue(name, 'timePercent'); | |
| 834 } | |
| 835 getTotalCount(name) { | |
| 836 return this.getTotalValue(name, 'count'); | |
| 837 } | |
| 838 getPagesByPercentImpact(name) { | |
| 839 var sortedPages = | |
| 840 this.pages.filter((each) => { | |
| 841 return each.get(name) !== undefined | |
| 842 }); | |
| 843 sortedPages.sort((a, b) => { | |
| 844 return b.get(name).timePercent - a.get(name).timePercent; | |
| 845 }); | |
| 846 return sortedPages; | |
| 847 } | |
| 848 } | |
| 849 Version.fromJSON = function(name, data) { | |
| 850 var version = new Version(name); | |
| 851 for (var page in data) { | |
| 852 version.add(Page.fromJSON(version, page, data[page])); | |
| 853 } | |
| 854 return version; | |
| 855 } | |
| 856 | |
| 857 | |
| 858 class Page { | |
| 859 constructor(version, name) { | |
| 860 this.name = name; | |
| 861 this.total = new GroupedEntry('Total', /.*Total.*/); | |
| 862 this.unclassified = new UnclassifiedEntry(this) | |
| 863 this.groups = [ | |
| 864 this.total, | |
| 865 new GroupedEntry('IC', /.*IC.*/), | |
| 866 new GroupedEntry('Optimize', | |
| 867 /StackGuard|.*Optimize.*|.*Deoptimize.*|Recompile.*/), | |
| 868 new GroupedEntry('Compile', /.*Compile.*|Parse.*/), | |
| 869 new GroupedEntry('Callback', /.*Callback$/), | |
| 870 new GroupedEntry('API', /.*API.*/), | |
| 871 new GroupedEntry('GC', /GC|AllocateInTargetSpace/), | |
| 872 new GroupedEntry('JavaScript', /JS_Execution/), | |
| 873 this.unclassified | |
| 874 ]; | |
| 875 this.entryDict = new Map(); | |
| 876 this.groups.forEach((entry) => { | |
| 877 entry.page = this; | |
| 878 this.entryDict.set(entry.name, entry); | |
| 879 }); | |
| 880 this.version = version; | |
| 881 } | |
| 882 add(entry) { | |
| 883 entry.page = this; | |
| 884 this.entryDict.set(entry.name, entry); | |
| 885 var added = false; | |
| 886 this.groups.forEach((group) => { | |
| 887 if (!added) added = group.add(entry); | |
| 888 }); | |
| 889 if (added) return; | |
| 890 this.unclassified.push(entry); | |
| 891 } | |
| 892 get(name) { | |
| 893 return this.entryDict.get(name) | |
| 894 } | |
| 895 getEntry(entry) { | |
| 896 if (entry === undefined) return undefined; | |
| 897 return this.get(entry.name); | |
| 898 } | |
| 899 get length() { | |
| 900 return this.versions.length | |
| 901 } | |
| 902 forEachSorted(referencePage, func) { | |
| 903 // Iterate over all the entries in the order they appear on the referenc e page. | |
|
nickie
2016/05/06 12:40:48
Bad formatting. Move two words to next line?
| |
| 904 referencePage.forEach((parent, referenceEntry) => { | |
| 905 var entry; | |
| 906 if (parent) parent = this.entryDict.get(parent.name); | |
| 907 if (referenceEntry) entry = this.entryDict.get(referenceEntry.name); | |
| 908 func(parent, entry, referenceEntry); | |
| 909 }); | |
| 910 } | |
| 911 forEach(fun) { | |
| 912 this.forEachGroup((group) => { | |
| 913 fun(undefined, group); | |
| 914 group.forEach((entry) => { | |
| 915 fun(group, entry) | |
| 916 }); | |
| 917 }); | |
| 918 } | |
| 919 forEachGroup(fun) { | |
| 920 this.groups.forEach(fun) | |
| 921 } | |
| 922 sort() { | |
| 923 this.groups.sort((a, b) => { | |
| 924 return b.time - a.time; | |
| 925 }); | |
| 926 this.groups.forEach((group) => { | |
| 927 group.sort() | |
| 928 }); | |
| 929 } | |
| 930 } | |
| 931 Page.fromJSON = function(version, name, data) { | |
| 932 var page = new Page(version, name); | |
| 933 for (var i = 0; i < data.length; i++) { | |
| 934 page.add(Entry.fromJSON(i, data[data.length - i - 1])); | |
| 935 } | |
| 936 page.sort(); | |
| 937 return page | |
| 938 } | |
| 939 | |
| 940 | |
| 941 class Entry { | |
| 942 constructor(position, name, time, timeVariance, timeVariancePercent, | |
| 943 count, | |
| 944 countVariance, countVariancePercent) { | |
| 945 this.position = position; | |
| 946 this.name = name; | |
| 947 this._time = time; | |
| 948 this._timeVariance = timeVariance; | |
| 949 this._timeVariancePercent = timeVariancePercent; | |
| 950 this._count = count; | |
| 951 this.countVariance = countVariance; | |
| 952 this.countVariancePercent = countVariancePercent; | |
| 953 this.page = undefined; | |
| 954 this.parent = undefined; | |
| 955 } | |
| 956 getCompareWithBaseline(value, property) { | |
| 957 if (baselineVersion == undefined) return value; | |
| 958 var baselineEntry = baselineVersion.getEntry(this); | |
| 959 if (!baselineEntry) return value; | |
| 960 if (baselineVersion === this.page.version) return value; | |
| 961 return value - baselineEntry[property]; | |
| 962 } | |
| 963 cssClass() { | |
| 964 return '' | |
| 965 } | |
| 966 get time() { | |
| 967 return this.getCompareWithBaseline(this._time, '_time'); | |
| 968 } | |
| 969 get count() { | |
| 970 return this.getCompareWithBaseline(this._count, '_count'); | |
| 971 } | |
| 972 get timePercent() { | |
| 973 var value = this._time / this.page.total._time * 100; | |
| 974 if (baselineVersion == undefined) return value; | |
| 975 var baselineEntry = baselineVersion.getEntry(this); | |
| 976 if (!baselineEntry) return value; | |
| 977 return (this._time - baselineEntry._time) / this.page.total._time * | |
| 978 100; | |
| 979 } | |
| 980 get timePercentVariancePercent() { | |
| 981 // Get the absolute values for the percentages | |
| 982 return this.timeVariance / this.page.total._time * 100; | |
| 983 } | |
| 984 getTimeImpact() { | |
| 985 return this.page.version.getTotalTime(this.name); | |
| 986 } | |
| 987 getTimePercentImpact() { | |
| 988 return this.page.version.getTotalTimePercent(this.name); | |
| 989 } | |
| 990 getCountImpact() { | |
| 991 return this.page.version.getTotalCount(this.name); | |
| 992 } | |
| 993 getPagesByPercentImpact() { | |
| 994 return this.page.version.getPagesByPercentImpact(this.name); | |
| 995 } | |
| 996 get isGroup() { | |
| 997 return false | |
| 998 } | |
| 999 get timeVariance() { | |
| 1000 return this._timeVariance | |
| 1001 } | |
| 1002 get timeVariancePercent() { | |
| 1003 return this._timeVariancePercent | |
| 1004 } | |
| 1005 } | |
| 1006 Entry.fromJSON = function(position, data) { | |
| 1007 return new Entry(position, ...data); | |
| 1008 } | |
| 1009 | |
| 1010 | |
| 1011 class GroupedEntry extends Entry { | |
| 1012 constructor(name, regexp) { | |
| 1013 super(0, 'Group-' + name, 0, 0, 0, 0, 0, 0); | |
| 1014 this.regexp = regexp; | |
| 1015 this.entries = []; | |
| 1016 } | |
| 1017 add(entry) { | |
| 1018 if (!entry.name.match(this.regexp)) return false; | |
| 1019 this._time += entry.time; | |
| 1020 this._count += entry.count; | |
| 1021 // TODO: sum up variance | |
| 1022 this.entries.push(entry); | |
| 1023 entry.parent = this; | |
| 1024 return true; | |
| 1025 } | |
| 1026 forEach(fun) { | |
| 1027 if (baselineVersion === undefined) { | |
| 1028 this.entries.forEach(fun); | |
| 1029 return; | |
| 1030 } | |
| 1031 // If we have a baslineVersion to compare against show also all entries from the | |
|
nickie
2016/05/06 12:40:48
Bad formatting. Move two words to next line?
| |
| 1032 // other group. | |
| 1033 var tmpEntries = baselineVersion.getEntry(this) | |
| 1034 .entries.filter((entry) => { | |
| 1035 return this.page.get(entry.name) == undefined | |
| 1036 }); | |
| 1037 | |
| 1038 // The compared entries are sorted by absolute impact. | |
| 1039 tmpEntries = tmpEntries.map((entry) => { | |
| 1040 var tmpEntry = new Entry(0, entry.name, 0, 0, 0, 0, 0, 0); | |
| 1041 tmpEntry.page = this.page; | |
| 1042 return tmpEntry; | |
| 1043 }); | |
| 1044 tmpEntries = tmpEntries.concat(this.entries); | |
| 1045 tmpEntries.sort((a, b) => { | |
| 1046 return a.time - b.time | |
| 1047 }); | |
| 1048 tmpEntries.forEach(fun); | |
| 1049 } | |
| 1050 sort() { | |
| 1051 this.entries.sort((a, b) => { | |
| 1052 return b.time - a.time; | |
| 1053 }); | |
| 1054 } | |
| 1055 cssClass() { | |
| 1056 if (this.page.total == this) return 'total'; | |
| 1057 return ''; | |
| 1058 } | |
| 1059 get isGroup() { | |
| 1060 return true | |
| 1061 } | |
| 1062 getVariancePercentForProperty(property) { | |
| 1063 var sum = 0; | |
| 1064 this.entries.forEach((entry) => { | |
| 1065 sum += entry[property + 'Variance'] * entry[property + | |
| 1066 'Variance']; | |
| 1067 }); | |
| 1068 return Math.sqrt(sum) / this['_' + property] * 100; | |
| 1069 } | |
| 1070 get timeVariancePercent() { | |
| 1071 return this.getVariancePercentForProperty('time') | |
| 1072 } | |
| 1073 get timeVariance() { | |
| 1074 return this.getVariancePercentForProperty('timePercent') | |
| 1075 } | |
| 1076 } | |
| 1077 | |
| 1078 class UnclassifiedEntry extends GroupedEntry { | |
| 1079 constructor(page) { | |
| 1080 super('Unclassified'); | |
| 1081 this.page = page; | |
| 1082 this._time = undefined; | |
| 1083 this._count = undefined; | |
| 1084 } | |
| 1085 add(entry) { | |
| 1086 this.entries.push(entry); | |
| 1087 entry.parent = this; | |
| 1088 return true; | |
| 1089 } | |
| 1090 forEachPageGroup(fun) { | |
| 1091 this.page.forEachGroup((group) => { | |
| 1092 if (group == this) return; | |
| 1093 if (group == this.page.total) return; | |
| 1094 fun(group); | |
| 1095 }); | |
| 1096 } | |
| 1097 get time() { | |
| 1098 if (this._time !== undefined) { | |
| 1099 return this.getCompareWithBaseline(this._time, '_time'); | |
| 1100 } | |
| 1101 this._time = 0; | |
| 1102 var t = this.page.total.time; | |
| 1103 this.forEachPageGroup((group) => { | |
| 1104 t -= group.time; | |
| 1105 }); | |
| 1106 this._time = Math.round(t); | |
| 1107 return this._time; | |
| 1108 } | |
| 1109 get count() { | |
| 1110 if (this._count !== undefined) { | |
| 1111 return this.getCompareWithBaseline(this._count, '_count'); | |
| 1112 } | |
| 1113 this._count = 0; | |
| 1114 var c = this.page.total.count; | |
| 1115 this.forEachPageGroup((group) => { | |
| 1116 c -= group.count; | |
| 1117 }); | |
| 1118 this._count = Math.round(c); | |
| 1119 return this._count; | |
| 1120 } | |
| 1121 } | |
| 1122 </script> | |
| 1123 </head> | |
| 1124 | |
| 1125 <body onmousemove="handleUpdatePopover(event)"> | |
| 1126 <h1>Runtime Stats Komparator</h1> | |
| 1127 | |
| 1128 <div id="results"> | |
| 1129 <div class="inline"> | |
| 1130 <h2>Data</h2> | |
| 1131 <form name="fileForm"> | |
| 1132 <p> | |
| 1133 <input id="uploadInput" type="file" name="files" onchange="handleLoadF ile();"> | |
| 1134 </p> | |
| 1135 </form> | |
| 1136 </div> | |
| 1137 <div class="inline hidden"> | |
| 1138 <h2>Result</h2> | |
| 1139 <div class="compareSelector"> | |
| 1140 Compare against: <select id="baseline" onchange="handleSelectBaseli ne(this, event)"></select><br/> | |
| 1141 <span style="color: #060">Green</span> the selected version above perfor ms | |
| 1142 better on this measurement. | |
| 1143 </div> | |
| 1144 </div> | |
| 1145 <div id="view"> | |
| 1146 </div> | |
| 1147 | |
| 1148 <div id="detailView" class="hidden"> | |
| 1149 <h2></h2> | |
| 1150 <div class="versionDetail inline"> | |
| 1151 <h3><span></span></h3> | |
| 1152 <table class="versionDetailTable" onclick="handleSelectDetailRow(this, e vent);"> | |
| 1153 <thead> | |
| 1154 <tr> | |
| 1155 <th class="version">Version </th> | |
| 1156 <th class="position">Pos. </th> | |
| 1157 <th class="value time">Time▴ </th> | |
| 1158 <th class="value time">Percent </th> | |
| 1159 <th class="value count">Count </th> | |
| 1160 </tr> | |
| 1161 </thead> | |
| 1162 <tbody></tbody> | |
| 1163 </table> | |
| 1164 </div> | |
| 1165 <div class="pageDetail inline"> | |
| 1166 <h3><span></span></h3> | |
| 1167 <table class="pageDetailTable" onclick="handleSelectDetailRow(this, even t);"> | |
| 1168 <thead> | |
| 1169 <tr> | |
| 1170 <th class="page">Page </th> | |
| 1171 <th class="position">Pos. </th> | |
| 1172 <th class="value time">Time </th> | |
| 1173 <th class="value time">Percent▾ </th> | |
| 1174 <th class="value count">Count </th> | |
| 1175 </tr> | |
| 1176 </thead> | |
| 1177 <tfoot> | |
| 1178 <tr> | |
| 1179 <td class="page">Total:</td> | |
| 1180 <td class="position"></td> | |
| 1181 <td class="value time"></td> | |
| 1182 <td class="value time"></td> | |
| 1183 <td class="value count"></td> | |
| 1184 </tr> | |
| 1185 </tfoot> | |
| 1186 <tbody></tbody> | |
| 1187 </table> | |
| 1188 </div> | |
| 1189 <div class="impactView inline"> | |
| 1190 <h3>Impact list for <span></span></h3> | |
| 1191 <table class="pageDetailTable" onclick="handleSelectDetailRow(this, even t);"> | |
| 1192 <thead> | |
| 1193 <tr> | |
| 1194 <th class="page">Name </th> | |
| 1195 <th class="value time">Time </th> | |
| 1196 <th class="value time">Percent▾ </th> | |
| 1197 <th class="">Top Pages</th> | |
| 1198 </tr> | |
| 1199 </thead> | |
| 1200 <tbody></tbody> | |
| 1201 </table> | |
| 1202 </div> | |
| 1203 </div> | |
| 1204 | |
| 1205 <div id="column" class="column"> | |
| 1206 <div class="header"> | |
| 1207 <select class="version" onchange="handleSelectVersion(this, event);"></s elect> | |
| 1208 <select class="pageVersion" onchange="handleSelectPage(this, event);"></ select> | |
| 1209 </div> | |
| 1210 <table class="list" onclick="handleSelectRow(this, event);"> | |
| 1211 <thead> | |
| 1212 <tr> | |
| 1213 <th class="position">Pos. </th> | |
| 1214 <th class="name">Name </th> | |
| 1215 <th class="value time">Time </th> | |
| 1216 <th class="value time">Percent </th> | |
| 1217 <th class="value count">Count </th> | |
| 1218 </tr> | |
| 1219 </thead> | |
| 1220 <tbody></tbody> | |
| 1221 </table> | |
| 1222 </div> | |
| 1223 </div> | |
| 1224 | |
| 1225 <div class="inline"> | |
| 1226 <h2>Usage</h2> | |
| 1227 <ol> | |
| 1228 <li>Build chrome with the <a href="https://codereview.chromium.org/1923893 002">extended runtime callstats</a>.</li> | |
| 1229 <li>Run callstats.py with a web-page-replay archive: | |
| 1230 <pre>./callstats.py run \ | |
| 1231 --replay-bin=$CHROME_SRC/third_party/webpagereplay/replay.py \ | |
| 1232 --replay-wpr=top25.wpr \ | |
| 1233 --js-flags="" \ | |
| 1234 --with-chrome=$CHROME_SRC/out/Release/chrome \ | |
| 1235 --sites-file=top25.json</pre> | |
| 1236 </li> | |
| 1237 <li>Move results file to a subdirectory: <code>mkdir $VERSION; mv *.txt $V ERSION</code></li> | |
| 1238 <li>Repeat from step 1 with a different configuration (e.g. <code>--js-fla gs="--nolazy"</code>).</li> | |
| 1239 <li>Create the final results file: <code>./callstats.py json $VERSION1 $VE RSION2 > result.json</code></li> | |
| 1240 <li>Use <code>results.json</code> on this site.</code> | |
| 1241 </ol> | |
| 1242 </div> | |
| 1243 | |
| 1244 <div id="popover"> | |
| 1245 <div class="popoverArrow"></div> | |
| 1246 <table> | |
| 1247 <tr> | |
| 1248 <td class="name" colspan="2"></td> | |
| 1249 </tr> | |
| 1250 <tr> | |
| 1251 <td>Page:</td> | |
| 1252 <td class="page"></td> | |
| 1253 </tr> | |
| 1254 <tr> | |
| 1255 <td>Version:</td> | |
| 1256 <td><span class="version"></span></td> | |
| 1257 <td class="compare"><span class="version"></span></td> | |
| 1258 </tr> | |
| 1259 <tr> | |
| 1260 <td>Time:</td> | |
| 1261 <td><span class="time"></span> ± <span class="timeVariance"></span></td> | |
| 1262 <td class="compare"><span class="time"></span> ± <span class="timeVarian ce"></span></td> | |
| 1263 </tr> | |
| 1264 <tr> | |
| 1265 <td>Percent:</td> | |
| 1266 <td><span class="percent"></span> ± <span class="percentVariance"></span ></td> | |
| 1267 <td class="compare"><span class="percent"></span> ± <span class="percent Variance"></span></td> | |
| 1268 </tr> | |
| 1269 <tr> | |
| 1270 <td>Count:</td> | |
| 1271 <td><span class="count"></span> ± <span class="countVariance"></span></t d> | |
| 1272 <td class="compare"><span class="count"></span> ± <span class="countVari ance"></span></td> | |
| 1273 </tr> | |
| 1274 <tr> | |
| 1275 <td>Overall Impact:</td> | |
| 1276 <td><span class="timeImpact"></span> / <span class="timePercentImpact">< /span></td> | |
| 1277 <td class="compare"><span class="timeImpact"></span> / <span class="time PercentImpact"></span></td> | |
| 1278 </tr> | |
| 1279 </table> | |
| 1280 </div> | |
| 1281 | |
| 1282 </body> | |
| 1283 | |
| 1284 </html> | |
| OLD | NEW |