The network tab in the DevTools is really useful, but the way I've done things, I've compared the outputs of two runs by taking on notes the questions I've had & then refreshing. Or keeping two windows open, which could get confusing. And when I had new questions, I'd reload & take new notes.
This has been good enough to get me to today, but it turns out there's always been a way to extract that as JSON. You can right click any of the entries & save the JSON. And this is great. It has everything from the Network tab:
console.log("entry:", Object.keys(requests[0]))
console.log("request:", Object.keys(requests[0].request))
console.log("response: ", Object.keys(requests[0].response))
entry: [
'_initiator',
'_priority',
'_resourceType',
'cache',
'connection',
'pageref',
'request',
'response',
'serverIPAddress',
'startedDateTime',
'time',
'timings'
]
request: [
'method',
'url',
'httpVersion',
'headers',
'queryString',
'cookies',
'headersSize',
'bodySize'
]
response: [
'status', 'statusText',
'httpVersion', 'headers',
'cookies', 'content',
'redirectURL', 'headersSize',
'bodySize', '_transferSize',
'_error'
]
I used it to write a little script that I'm going to use when I play performance golf on the worththetime.info
const fs = require('fs')
const file = JSON.parse(fs.readFileSync('result.har'))
const extractTiming = (timingData) => {
return Object.values(timingData).map(e => Number(e)).filter(e => e > 0).reduce((e, f) => e+f)
}
const requests = file.log.entries
const timings = requests.map(r => r.timings)
let total = 0;
const totalTime = timings
.map(t => extractTiming(t))
.reduce((t, acc) => t+acc)
---
num requests is: 7
total time 631.9129998691976
But you could also use it to do things like assert there are no 302s:
const statuses = requests.map(r => r.response.status)
const no302s = statuses.every(s => s !== 302)
console.log('statuses: ', statuses)
console.log('no redirects?', no302s)
---
statuses: [
200, 302, 200,
200, 302, 200,
200
]
no redirects? false
You can do whatever you want!
... but none are quite as comprensible
If you save the profiler the output is a few thousand lines of this:
{"args":{"name":"Browser"},"cat":"__metadata","name":"process_name","ph":"M","pid":10802,"tid":0,"ts":0},
{"args":{"name":"Renderer"},"cat":"__metadata","name":"process_name","ph":"M","pid":96133,"tid":0,"ts":0},
{"args":{},"cat":"disabled-by-default-devtools.timeline","dur":13,"name":"RunTask","ph":"X","pid":96133,"tdur":11,"tid":13571,"ts":383268870474,"tts":756385},
The Memory profiler also has this, though it looks even more tied to the layout of that tab. I guess it's possible that it can be consumed by a conventional memory profiler. ... but over all none of the
You could go a step further and use that to fetch the .HAR files. Puppeteer is a tool for letting you work with chrome headlessly. I would have thought that the ability to get .HAR files would be built in, but according to this ticket it's not.
There's still a few options:
I haven't needed to do this yet, so I haven't looked into them. For me, right now it's not "worth the time"
Lighthouse must be using some of these same data sources in it's reports. I'd bet it uses Puppeteer directly to fetch the, but even if not, I'm certain that it has another way to access the same data (via the protocol) & it reshapes things into more human developer.
I'm glad I found this, and hope you found it useful. Good day!