HAR comparison
- - - -Timeline
+ +Visual progress
+Lines: the selected runs. Light color: from the slowest to the fastest run.
+ +Shaded red: the two runs differ by 20 percentage points or more in visual progress.
+ +Waterfall
+Drag on a waterfall to draw, or click to add text. Drag a drawing to move it. Esc stops drawing.
All metrics
+ + +Request changes
+ + + + +Visual Progress
' + - '' + - '' + - '- ' +
- '
- ' + h(d.config.har1.label) + ' ' + - '
- ' + h(d.config.har2.label) + ' ' + - '
| ' +
- ' ' +
- 'Metric' +
- '' +
- '' +
- '' +
- '' +
- ' | ';
- html += '' + h(config.har1.label) + - '' + - ' | '; - html += '' + h(config.har2.label) + - '' + - ' | '; - html += 'Δ | '; - html += '|
|---|---|---|---|---|
| Run | ';
- if (d.runs1.length > 1) {
- html += '';
+function summaryTemplate(d) {
+ let html = ' ' +
+ ' ';
+
+ if (d.modeBar) {
+ html += '' + h(d.url) + '' + + '' + h(d.details) + ' ' + each(d.sides, function (s) {
+ return '' +
+ '' + h(s.label) + ' ' + h(s.when) + ' · ' + h(s.runs) +
+ '' +
+ '';
+ }) + ' | '; - if (d.runs2.length > 1) { - html += ''; + if (d.outlierNote) html += pill('warn', d.outlierNote); } - html += ' | ' + emptyDiff + '||
| URL | ' + - '' + h(p1.url) + ' | ' + - '' + h(p2.url) + ' | ' + - emptyDiff + '||
| Date | ' + - '' + h(formatDate(p1.meta.startedDateTime)) + ' | ' + - '' + h(formatDate(p2.meta.startedDateTime)) + ' | ' + - emptyDiff + '||
| Browser | ' + - '' + (p1.meta.browser ? h(p1.meta.browser.name) + ' ' + h(p1.meta.browser.version) : '') + ' | ' + - '' + (p2.meta.browser ? h(p2.meta.browser.name) + ' ' + h(p2.meta.browser.version) : '') + ' | ' + - emptyDiff + '||
| Connectivity | ' + - '' + h(p1.meta.connectivity) + ' | ' + - '' + h(p2.meta.connectivity) + ' | ' + - emptyDiff + '||
| Total | ' + - '' + p1.requests + ' (' + formatBytes(p1.transferSize) + ' / ' + formatBytes(p1.contentSize) + ') | ' + - '' + p2.requests + ' (' + formatBytes(p2.transferSize) + ' / ' + formatBytes(p2.contentSize) + ') | ' + - diffCell(p1.transferSize, p2.transferSize, formatBytes) + '||
| ' + label + ' | ' + - '' + a.requests + ' (' + formatBytes(a.transferSize) + ' / ' + formatBytes(a.contentSize) + ') | ' + - '' + b.requests + ' (' + formatBytes(b.transferSize) + ' / ' + formatBytes(b.contentSize) + ') | ' + - diffCell(a.transferSize, b.transferSize, formatBytes) + '||
| Image | ' + - '' + img1.requests + ' (' + formatBytes(img1.transferSize) + ') | ' + - '' + img2.requests + ' (' + formatBytes(img2.transferSize) + ') | ' + - diffCell(img1.transferSize, img2.transferSize, formatBytes) + '||
| Metric | ' + + '' + h(d.labelA) + ' | ' + + '' + h(d.labelB) + ' | ' + + 'Change | ' + + 'Runs vs ' + h(d.referenceLabel) + + ' | ' + + '
| ' + h(r.label) + count + fold + ' | ||||
| ' + h(r.label) + ' | ' + + '' + h(r.aText) + '' + h(r.aRange) + ' | ' + + '' + h(r.bText) + '' + h(r.bRange) + ' | ' + + '' + pill(r.cls, r.dText) + '' + h(r.pText) + ' | ' + + '' + (r.showDots + ? runDots(r.dotsA, 1, r.reference, d.runA) + runDots(r.dotsB, 2, r.reference, d.runB) + : '') + ' |
No requests match. Lower the size limit or pick another filter.
'; } + const sortButton = (id, label) => ''; + return summary + filters + + '| ' + sortButton('url', 'URL') + ' | Type | ' + + '' + h(d.labelA) + ' | ' + + '' + h(d.labelB) + ' | ' + + '' + sortButton('change', 'Change') + ' |
|---|---|---|---|---|
| ' + h(formatURL(r.url)) + ' | ' + + '' + h(r.type) + ' | ' + + '' + h(r.aText) + ' | ' + h(r.bText) + ' | ' + + '' + + '' + h(r.dText) + ' |
| ' + h(eventLabel) + ' | ' + - '' + h(config.har1.label) + ' | ' + - '' + h(config.har2.label) + ' | ' + - 'Δ | ' + - '
|---|
Red marks on the timeline are long tasks: the main thread was busy and the page could not paint or respond.
' : ''); +} - html += 'Captures
' + links.join(' · ') + '
' : '') + 'Filmstrip
' + + return 'Filmstrip
' + + 'First Party vs Third Party content
'; - if (p1.firstPartyRegEx === p2.firstPartyRegEx) { - html += 'Using ' + h(p1.firstPartyRegEx) + ' as --firstParty parameter.
'; - } else { - html += 'Using ' + h(p1.firstPartyRegEx) + ' as --firstParty parameter for ' + - h(config.har1.label) + ' and ' + h(p2.firstPartyRegEx) + ' for ' + h(config.har2.label) + '.
'; - } - html += ''; - html += '| Metric | ' + - '' + h(config.har1.label) + ' | ' + - '' + h(config.har2.label) + ' | ' + - '
|---|---|---|
| ' + label + ' ' + - ' | ' + - '' + p1Cell + ' | ' + - '' + p2Cell + ' |
| ' + h(key) + ' | ' + - '' + cellFn(entry) + ' | ' + - '' + cellFn(contentTypes2 ? contentTypes2[key] : null) + ' | ' + - '
| First party cookies | ' + - '' + (p1.firstParty.cookies != null ? p1.firstParty.cookies : '') + ' | ' + - '|
| Third party cookies | ' + - '' + (p1.thirdParty.cookies != null ? p1.thirdParty.cookies : '') + ' | ' + - '
Domains
'; - html += ''; - html += '| Domain | ' + - '' + h(config.har1.label) + ' Request | ' + - '' + h(config.har2.label) + ' Request | ' + - '' + h(config.har1.label) + ' Size | ' + - '' + h(config.har2.label) + ' Size | ' + - '
|---|---|---|---|---|
| ' + h(domain.name) + ' ' + - ' | ' + - '' + (domain.firstPage ? domain.firstPage.requests : '') + ' | ' + - '' + (domain.secondPage ? domain.secondPage.requests : '') + ' | ' + - '' + (domain.firstPage ? formatBytes(domain.firstPage.transferSize) : '') + ' | ' + - '' + (domain.secondPage ? formatBytes(domain.secondPage.transferSize) : '') + ' | ' + - '
| Total time spent HAR 1 ' + - (domain.firstPage ? each(domain.firstPage.timings, function (val, key) { - return ' ' + h(key) + ' : ' + val.toFixed(0) + ' '; - }) : '') + - ' | ' +
- ' Total time spent HAR 2 ' + - (domain.secondPage ? each(domain.secondPage.timings, function (val, key) { - return ' ' + h(key) + ' : ' + val.toFixed(0) + ' '; - }) : '') + - ' | |||
Request/response transfer size difference (larger than 1 KB)
'; - html += ''; - - if (!d.requestDiff.length) { - html += 'There are no difference in size of the requests/responses.
'; - return html; - } - - const t = d.total; - - html += '| URL | ' + - '' + h(d.config.har1.label) + ' | ' + - '' + h(d.config.har2.label) + ' | ' + - 'Diff | ' + - '-' + formatBytes(-r.diff) + ' | '; - } else { - diffCell = '+' + formatBytes(r.diff) + ' | '; - } - } else if (r.har1 !== undefined) { - diffCell = 'Removed | '; - } else { - diffCell = 'New | '; - } - return '
|---|---|---|---|---|
| ' + h(formatURL(r.url)) + ' | ' + - '' + formatBytes(r.har1) + ' | ' + - '' + formatBytes(r.har2) + ' | ' + - diffCell + - '||
| Total | ' + - '' + formatBytes(t.har1) + ' | ' + - '' + formatBytes(t.har2) + ' | ' + - (t.diff < 0 - ? '-' + formatBytes(-t.diff) + ' | ' - : '+' + formatBytes(t.diff) + ' | ') + - '
| Summary of request/response difference | ' + - 'Size | ' + - '|
|---|---|---|
| New (' + t.new + ') | ' + formatBytes(t.newBytes) + ' | |
| Removed (' + t.removed + ') | -' + formatBytes(t.removedBytes) + ' | |
| Increased (' + t.increased + ') | ' + formatBytes(t.increasedBytes) + ' | |
| Decreased (' + t.decreased + ') | -' + formatBytes(-t.decreasedBytes) + ' | |
| Total | ' + - (t.diff < 0 - ? '-' + formatBytes(-t.diff) + ' | ' - : '+' + formatBytes(t.diff) + ' | ') + - '
-