- Stop the next cookie's name leaking into a
Domain=attribute when a HAR concatenates multipleSet-Cookieresponse headers into one value joined by\n. The captured domain now stops at the newline.
- Node.js 22 is minumium.
- Classify
HTTP/3/HTTP/3.0connections ash3(previously only the lowercaseh3/h3-29shorthand was recognised — the canonical form fell through toh1) #128. - Parse
Cache-Controldirectives case-insensitively (RFC 7234 §5.2).Max-Age=42is now read as 42 instead of 0, andNo-Cache/No-Storeare honoured #128. - Replace the deprecated
url.parse(Node DEP0169) with the WHATWGURLparser ingetHostname#128. - Stop throwing in
getDocumentRequestswhen a page has no matching entries — return an empty array instead #128. missingCompressionwas flagging every large text asset, including gzipped ones, becauseheaders.flattenwraps values in arrays and the encoding check compared the array to a string. Unwrap before comparing, accept compound codings (br, gzip), and recognisezstd#129.- Match the
Domain=cookie attribute case-insensitively (RFC 6265 §5.2) so third-party cookies set with lowercasedomain=are detected #129. - Recognise common two-label public suffixes (
.co.jp,.com.br,.com.au, ...) ingetMainDomainso the auto-generated first-party regex isn't wrong for non-.co.ukcountry domains #129. defaultContentTypesnow includesfaviconso every page has a consistent shape (matches the example in the README) #129.xmlis now considered formissingCompressionreporting #129.engines.nodebumped from>=8.9.0to>=22.0.0(the current Node.js LTS), and the GitHub Actions matrix now runs on Node 22 + 24 #132, #133.- Test runner switched from Mocha + Chai to AVA, matching the rest of the sitespeed.io / browsertime ecosystem. Test helpers no longer depend on bluebird or lodash #133.
- ESLint upgraded from 8 to 9 with the new flat config (
eslint.config.jsreplaces.eslintrc.jsonand.eslintignore) #133. - All devDependencies bumped to current major versions: prettier 3, browserify 17, browserify-banner 2, @babel/core + preset-env 7.29, jsdoc 4. The abandoned
uglify-esis replaced byterser, andmkdirpis dropped in favour of nativefs.mkdirSync({recursive:true})in the browserify script #133.
- CLI can now read a HAR from stdin:
pagexray -or piping intopagexraywith no path argument #131. - CLI prints a friendly error to stderr and exits 1 when the file is missing or the input isn't valid JSON (previously threw a raw Node stack trace) #131.
- README updated to drop the long-removed
cookieStatsexample block and document fields added across 3.x / 4.x (fullyLoaded,afterOnLoad,afterOnContentLoad,renderBlocking,googleWebVitals,cpu,firstPartyRegEx) #130.
- Surface page-level style recalculation work on
renderBlocking.recalculateStyle(elements touched and duration before FCP/LCP) so consumers can show how much style work happened on the way to each paint milestone #127.
- Added a safer header check #125.
- If the meta section from a HAR file from Browsertime was missing, we didn't catch that. Fixed in #124.
- Update to latest minimist #122.
- Added missing SSL timings to the time per domain #117
- Bumped minimist to 1.2.6
- Fallback if mime types aren't mapped and use file endings. At the moment we fallback for some of the font types #109.
- Added missing in_body_parser_blocking render blocking info for Chrome.
- Include request method per asset #105.
- Attach info about render blocking assets coming/working in Chrome 92 #104.
- Attach Google Web Vitals data from Browsertime #101.
- The new header structure actually sucked. Instead follow other tools and flatten headers returning an array #98.
- Ooops, missed to expose the third party cookie data #97.
- Get third party domains for cookies #96.
-
Request/response headers are now returned with name/value keys to handle headers with the same name. This will only affect you if you get assets from PageXray #93.
-
Removed cookie statistics field since it was broken. Report number of first and third party cookies instead.
- PageXray can categorise connections as H3 #95.
- If an asset has the HTML/text content it will be added to the asset section #90.
- Updated minimist to 1.2.5
- Generic copy meta tag from sitespeed.io instead of specific fields #80.
- Updated dependencies #79.
- Fix for categorise Wikipedia first/third party correct #76
- Handle pages that doesn't have any requests #75.
- Counting the amount of requests per page, was broken in some cases. The order of the entries in the HAR file used to matter, fixed in #74.
- Test first party domain on the actual domain instead on the URL #73 since some measuring scripts include the URL in GET parameters that break the calculation.
- If the HAR contains a URL for a page, use that URL (to get the right URL for a SPA) #69
- Using a HAR file from Browsertime without meta data made converting fail.
- If you don't add your own firstparty regex, we set a default one based on the hostname. If your hostname is www.sitespeed.io we will use .sitespeed. #68.
- We missed video/audio/xml/pdf as content type so we categorised them as others. Lets be specific instead #67.
- If one of the WebPageTest runs failed, PageXray was broken.
- Count requests/size that happens after onContentLoad and onLoad.
- Calculate fullyLoaded.
- Better way to handle URL redirects -> more correct and avoid errors.
- Collect the size of 304 responses see sitespeed.io #1963
- Adding totalTime to results for each asset and domain #59.
- Include CPU metrics from Browsertime. Also align the WebPageTest CPU metrics with Browsertime (cpu.events.* instead of cpu.*).
- If the HTTP version is unknown in the HAR, categorize it as unknown instead of h1/empty #54.
- WebPageTest HAR files sometimes has request with timings that probably is wrong #52
- Fixed infinite loop for getting redirects URLs #50.
- Chrome strips everything after # in the URL in the HAR, Firefox keeps it. Handle both #49.
- We moved to the NodeJS 8.x since it is now LTS.
- Har files that includes the same url loaded with different http version (h1 vs h2) are now parsed correctly.
- Handle redirects to paths (e.g. /foo) and convert to absolute urls.
- Fix expires and timeSinceLastModified parsing for invalid dates.
- Avoid error if optional entry timings are missing in HAR.
- Get the PageXray version with --version.
- You can now run PageXray in the browser! Check Github releases to download that version.
- If the HAR is generated with sitespeed.io > 5.4.3, we pickup some extra meta data: connection type, URL to the result page, URL to the video, URL to the screenshot. And we also add the browser and version if that is availible.
- Pickup firstParty/thirdParty config from the HAR, override with config.
- Collect timings per domain.
- Collect timings per timing type instead of total. This change is not backward compatible and you need to calculate the total yourself.
- Collect assets that have 2XX status code instead of just strict 200. Thanks @vio for the PR.
- Calculating timing for an assets included both SSL and Connect time, that is wrong since connect time includes SSL time.
- Making sure default content types values exist even if they don't
- Added breakdown for first vs third party asset content types
- documentRedirects should be 0 when there's no redirects (not -1).
- Match fonts from Google Fonts.
- Collect number of responses missing compression (that can be compressed)
- Get cookies from the request instead of the response (great @tobli!)
- Collect cookie stats for a page (max/min median etc)
- Collect cookie stats for first vs third parties
- Collect total download time for each response
- Collect number of cookies per asset
- Internal: We moved to airbnb eslint style rules.
- Collect total number of domains in totalDomain.
-
Always report default content types (html, css, javascript etc) + add others. Before we only added the types that was in the HAR.
-
Make sure content size is > -1 (sometimes Firefox HAR have assets that are -1 in size).
Even cleaner structure for first party vs third party assets.
New structure for domains to be able to support 1st vs 3rd party assets. Supply a regex for 1st party domains and you will get stats for 1st vs 3rd.
- Fix content type matching for JSON.
- Renamed 'others' content type to 'other' for consistency.
- New name new game. The project is now known as project PageXray.
- Collect the full redirect chain
- Removed console log.
- Create statistics per page instead of take stats for all pages.