PageXray

HAR files are great, but it is hard to see how a page is put together by reading one. PageXray converts a HAR into a compact JSON summary that is easier to read and easier to work with. We use it internally in the Coach and sitespeed.io (Node.js) and directly in the browser at compare.sitespeed.io.
What does PageXray collect?
- Size and number of requests per content type.
- Size and number of requests per domain.
- Number of requests per response code.
- The base domain and the HTTP version of the main HTML document.
- Every asset (response) with: type, URL, size, expires (max-age/expires normalised to seconds), status code, time since last modified (normalised to seconds), HTTP version, and all request and response headers.
- If the HAR comes from sitespeed.io you also get visual metrics like SpeedIndex.
Install
npm install pagexray -g Run
pagexray /path/to/my.har Pretty-print the JSON output:
pagexray --pretty /path/to/my.har Include info for every request and response:
pagexray --includeAssets /path/to/my.har To use PageXray from Node.js:
const pagexray = require('pagexray');
const har = // your HAR
const pages = pagexray.convert(har); Using PageXray in your browser
Include the latest pagexray.min.js from the releases page on your page. PageXray is exposed as window.PageXray:
const pageXray = window.PageXray.convert(har); Output
All sizes are in bytes. Expires and timeSinceLastModified are in seconds.
[
{
"url": "https://www.sitespeed.io/",
"meta": {
"browser": {
"name": "Chrome",
"version": "60.0.3112.78"
},
"startedDateTime": "2017-08-24T18:26:29.077Z",
"connectivity": "native",
"title": "Sitespeed.io - Welcome to the wonderful world of Web Performance run 1"
},
"finalUrl": "https://www.sitespeed.io/",
"baseDomain": "www.sitespeed.io",
"documentRedirects": 0,
"redirectChain": [],
"transferSize": 98791,
"contentSize": 120776,
"headerSize": 0,
"requests": 10,
"missingCompression": 0,
"httpType": "h2",
"httpVersion": "HTTP/2.0",
"contentTypes": {
"html": {
"transferSize": 8479,
"contentSize": 28279,
"headerSize": 0,
"requests": 1
},
"css": {
"transferSize": 0,
"contentSize": 0,
"headerSize": 0,
"requests": 0
},
"javascript": {
"transferSize": 0,
"contentSize": 0,
"headerSize": 0,
"requests": 0
},
"image": {
"transferSize": 87309,
"contentSize": 85979,
"headerSize": 0,
"requests": 8
},
"font": {
"transferSize": 0,
"contentSize": 0,
"headerSize": 0,
"requests": 0
},
"favicon": {
"transferSize": 3003,
"contentSize": 6518,
"headerSize": 0,
"requests": 1
}
},
"assets": [],
"responseCodes": {
"200": 10
},
"firstParty": {},
"thirdParty": {},
"domains": {
"www.sitespeed.io": {
"transferSize": 98791,
"contentSize": 120776,
"headerSize": -10,
"requests": 10,
"timings": {
"blocked": 169,
"dns": 0,
"connect": 0,
"send": 6,
"wait": 3624,
"receive": 104
}
}
},
"expireStats": {
"min": 600,
"median": 31536000,
"max": 31536000,
"total": 283824600,
"values": 10
},
"lastModifiedStats": {
"min": 733347,
"median": 733444,
"max": 733480,
"total": 7334359,
"values": 10
},
"cookieStats": {
"min": 0,
"median": 0,
"max": 0,
"total": 0,
"values": 10
},
"totalDomains": 1,
"visualMetrics": {
"FirstVisualChange": 617,
"SpeedIndex": 625,
"VisualComplete85": 617,
"LastVisualChange": 1033,
"VisualProgress": {
"0": 0,
"617": 98,
"633": 98,
"667": 98,
"850": 98,
"1033": 100
}
}
}
]