289 lines
9.8 KiB
Plaintext
289 lines
9.8 KiB
Plaintext
mixin rowHeading(items)
|
|
thead
|
|
tr
|
|
each item in items
|
|
th= item
|
|
|
|
mixin numberCell(title, number)
|
|
td.number(data-title=title)= number
|
|
|
|
mixin sizeCell(title, size)
|
|
td.number(data-title=title, data-value= size)= h.size.format(size)
|
|
|
|
- const wpt = pageInfo.data.webpagetest.run ? pageInfo.data.webpagetest.run : pageInfo.data.webpagetest.pageSummary.data.median
|
|
- const wptRoot = pageInfo.data.webpagetest.run ? pageInfo.data.webpagetest : pageInfo.data.webpagetest.pageSummary.data;
|
|
- const wptRun = runNumber? runNumber : 1
|
|
|
|
a
|
|
h2 WebPageTest
|
|
p.small Metrics and data collected using #{options.webpagetest.host}.
|
|
if wptRoot.summary
|
|
a(href= wptRoot.summary) Check
|
|
| the result page on WebPageTest.
|
|
else
|
|
a(href= pageInfo.data.webpagetest.run.firstView.pages.details) Check
|
|
| the individual result page on WebPageTest.
|
|
|
|
.row
|
|
.one-half.column
|
|
table
|
|
tr
|
|
th Metric
|
|
th Value
|
|
if wptRoot.from
|
|
tr
|
|
td From:
|
|
td !{wptRoot.from}
|
|
if wptRoot.id
|
|
tr
|
|
td Id:
|
|
td
|
|
a(href= wptRoot.summary) #{wptRoot.id}
|
|
if wptRoot.tester
|
|
tr
|
|
td Tester:
|
|
td #{wptRoot.tester}
|
|
if wpt.firstView
|
|
tr
|
|
td Browser:
|
|
td #{wpt.firstView.browser_name}
|
|
tr
|
|
td Version:
|
|
td #{wpt.firstView.browser_version}
|
|
tr
|
|
td Render (first view):
|
|
td #{wpt.firstView.render}
|
|
tr
|
|
td Speed Index (first view):
|
|
td #{wpt.firstView.SpeedIndex}
|
|
tr
|
|
td Last Visual Change (first view):
|
|
td #{wpt.firstView.lastVisualChange}
|
|
if wpt.repeatView
|
|
tr
|
|
td Render (repeat view):
|
|
td #{wpt.repeatView.render}
|
|
tr
|
|
td SpeedIndex (repeat view):
|
|
td #{wpt.repeatView.SpeedIndex}
|
|
tr
|
|
td Last Visual Change (repeat view):
|
|
td #{wpt.repeatView.lastVisualChange}
|
|
|
|
.one-half.column
|
|
img.u-max-full-width(src='data/screenshots/wpt-' + wptRun + '-firstView.png', alt='Screenshot')
|
|
|
|
.downloads
|
|
- const harEnding = options.gzipHAR ? '.har.gz' : '.har'
|
|
- const harName = 'data/webpagetest' + harEnding
|
|
- const harDownloadName = downloadName + '-webpagetest-' + harEnding
|
|
|
|
a.button.button-download(href=harName, download=downloadName) Download HAR
|
|
if options.webpagetest.timeline
|
|
- const tracePath = 'data/trace-' + wptRun + '-wpt-firstView.json.gz'
|
|
a.button.button-download(href=tracePath, download=downloadName + 'trace-' + wptRun + '-wpt-firstView.json.gz') Download first view timeline
|
|
if wpt.repeatView
|
|
- const tracePathRepeat = 'data/trace-' + wptRun + '-wpt-repeatView.json.gz'
|
|
a.button.button-download(href=tracePathRepeat, download=downloadName + 'trace-' + wptRun + '-wpt-repeatView.json.gz') Download repeat view timeline
|
|
|
|
each view in ['firstView', 'repeatView']
|
|
- const median = wpt[view];
|
|
if median
|
|
h2 #{view === 'firstView' ? 'First View': 'Repeat View'}
|
|
if options.webpagetest.video
|
|
a#visualmetrics
|
|
h3 Visual Metrics
|
|
.row
|
|
.one-half.column
|
|
table
|
|
tr
|
|
th(colspan='2') Visual Metrics
|
|
tr
|
|
td Render
|
|
+numberCell('Render', median.render)
|
|
tr
|
|
td Speed Index
|
|
+numberCell('SpeedIndex', median.SpeedIndex)
|
|
tr
|
|
td Visual Complete 85%
|
|
+numberCell('Visual Complete 85%', median.visualComplete85)
|
|
tr
|
|
td Last Visual Change
|
|
+numberCell('Last Visual Change', median.lastVisualChange)
|
|
if median.FirstInteractive
|
|
tr
|
|
td First Interactive
|
|
+numberCell('First Interactive', median.FirstInteractive)
|
|
if median.TimeToInteractive
|
|
tr
|
|
td Time To Interactive
|
|
+numberCell('Time To Interactive', median.TimeToInteractive)
|
|
if median.LastInteractive
|
|
tr
|
|
td Last Interactive
|
|
+numberCell('Last Interactive', median.LastInteractive)
|
|
|
|
.one-half.column
|
|
if median.videoFrames
|
|
table
|
|
tr
|
|
th(colspan='2') Visual Progress
|
|
- let lastProgress = -1
|
|
each frame in median.videoFrames
|
|
if lastProgress !== frame.VisuallyComplete
|
|
- lastProgress = frame.VisuallyComplete
|
|
tr
|
|
td #{frame.VisuallyComplete}
|
|
td #{frame.time} ms
|
|
else
|
|
p Missing WebPageTest visual metrics
|
|
|
|
a#timingsandpagemetrics
|
|
h3 Timing and page metrics
|
|
.row
|
|
.one-half.column
|
|
table
|
|
th(colspan='2') Timings
|
|
tr
|
|
td TTFB
|
|
+numberCell('TTFB', median.TTFB)
|
|
if median.firstPaint
|
|
tr
|
|
td First paint
|
|
+numberCell('First Paint', median.firstPaint.toFixed(0))
|
|
tr
|
|
td DOM loading
|
|
+numberCell('DOM loading', median.domLoading)
|
|
tr
|
|
td DOM interactive
|
|
+numberCell('DOM interactive', median.domInteractive)
|
|
tr
|
|
td Load Time
|
|
+numberCell('Load Time', median.loadTime)
|
|
tr
|
|
td Fully Loaded
|
|
+numberCell('Fully Loaded', median.fullyLoaded)
|
|
if (median.userTimes)
|
|
each value, key in median.userTimes
|
|
tr
|
|
td #{key}
|
|
+numberCell(key, value)
|
|
.one-half.column
|
|
table
|
|
tr
|
|
th(colspan='2') Page metrics
|
|
tr
|
|
td Requests
|
|
+numberCell('Requests', median.requestsFull)
|
|
tr
|
|
td Connections
|
|
+numberCell('Connections', median.connections)
|
|
tr
|
|
td DOM Elements
|
|
+numberCell('DOM Elements', median.domElements)
|
|
tr
|
|
td Total image size
|
|
+sizeCell('Image total', median.image_total)
|
|
tr
|
|
td bytesOut
|
|
+sizeCell('bytesOut', median.bytesOut)
|
|
tr
|
|
td bytesOutDoc
|
|
+sizeCell('bytesOutDoc', median.bytesOutDoc)
|
|
tr
|
|
td bytesIn
|
|
+sizeCell('bytesIn', median.bytesIn)
|
|
tr
|
|
td bytesInDoc
|
|
+sizeCell('bytesInDoc', median.bytesInDoc)
|
|
if median.certificate_bytes
|
|
tr
|
|
td Certificates size
|
|
+sizeCell('certificate_bytes', median.certificate_bytes)
|
|
|
|
//- You need to have timeline or right trace categories to get the timings
|
|
//- that is default now on WebPageTest.org
|
|
if (median.chromeUserTiming)
|
|
.row
|
|
.column
|
|
table
|
|
tr
|
|
th(colspan='2') Chrome User Timings
|
|
//- The WebPageTest APi isn't concistent
|
|
//- Per run it is an array
|
|
if Array.isArray(median.chromeUserTiming)
|
|
each value in median.chromeUserTiming
|
|
tr
|
|
td #{value.name}
|
|
td #{value.time}
|
|
else
|
|
each value, key in median.chromeUserTiming
|
|
tr
|
|
td #{key}
|
|
td #{value}
|
|
h3 Waterfall
|
|
img.u-max-full-width(src='data/waterfall/wpt-waterfall-' + wptRun + '-' + view + '.png', alt='Waterfall view')
|
|
h3 Connection view
|
|
img.u-max-full-width(src='data/waterfall/wpt-waterfall-connection' + wptRun + '-' + view + '.png', alt='Connection view')
|
|
|
|
h3 Request per content type
|
|
.responsive
|
|
if median.breakdown
|
|
table(data-sortable, id='contentSize')
|
|
+rowHeading(['Type', 'size', 'size uncompressed', 'requests'])
|
|
each value, contentType in median.breakdown
|
|
tr
|
|
td(data-title='Content Type') #{contentType}
|
|
+sizeCell('Size', median.breakdown[contentType].bytes)
|
|
+sizeCell('Size uncompressed', median.breakdown[contentType].bytesUncompressed)
|
|
+numberCell('Requests', median.breakdown[contentType].requests)
|
|
else
|
|
p Missing size data
|
|
|
|
h3 Request and size per domain
|
|
.responsive
|
|
if median.domains
|
|
table(data-sortable, id='contentSizePerDomain')
|
|
+rowHeading(['Domain', 'size', 'requests', 'connections'])
|
|
each value, domain in median.domains
|
|
tr
|
|
td(data-title='Domain') #{domain}
|
|
+sizeCell('Size', median.domains[domain].bytes)
|
|
+numberCell('Requests', median.domains[domain].requests)
|
|
+numberCell('Connections', median.domains[domain].connections)
|
|
else
|
|
p Missing domain data
|
|
//- WebPageTest.org has custom metrics by default
|
|
if (median.custom)
|
|
h3 Custom metrics
|
|
.row
|
|
.column
|
|
table
|
|
each key in median.custom
|
|
tr
|
|
td #{key}
|
|
td.break #{median[key]}
|
|
//- Not a great fan of JSON with dots ...
|
|
if (median['lighthouse.BestPractices'])
|
|
h3 Lighthouse
|
|
.row
|
|
.column
|
|
table
|
|
tr
|
|
td Best Practices Score
|
|
td #{median['lighthouse.BestPractices']}
|
|
tr
|
|
td Estimated Input Latency
|
|
td #{median['lighthouse.Performance.estimated-input-latency']}
|
|
tr
|
|
td First Interactive
|
|
td #{median['lighthouse.Performance.first-interactive']}
|
|
tr
|
|
td Accessibility Score
|
|
td #{median['lighthouse.Accessibility']}
|
|
tr
|
|
td SEO Score
|
|
td #{median['lighthouse.SEO']}
|
|
tr
|
|
td Progressive Web App Score
|
|
td #{median['lighthouse.ProgressiveWebApp']} |