Releases: sitespeedio/sitespeed.io
Releases · sitespeedio/sitespeed.io
41.3.3
What's Changed
- Chain downstream release workflows via workflow_dispatch by @soulgalore in #4786
Full Changelog: v41.3.2...v41.3.3
41.3.2
What's Changed
- Bump step-security/harden-runner to v2.19.4 by @soulgalore in #4782
- Sign Docker release images and attach SBOM + provenance by @soulgalore in #4783
- Add more agent info by @soulgalore in #4785
Full Changelog: v41.3.1...v41.3.2
41.3.1
What's Changed
- Try the slim build by @soulgalore in #4777
- Add security file by @soulgalore in #4778
- Prepare the public code block by @soulgalore in #4779
- Run releases via GitHub Actions with npm provenance and SBOM by @soulgalore in #4780
- Let release/feed.js fall back to GitHub when siblings aren't on disk by @soulgalore in #4781
Full Changelog: v41.3.0...v41.3.1
v41.3.0
v41.2.1
Fixed
- Unblock the arm64 Docker release build by bumping the QEMU
binfmtemulator to a 9.2 build that handles modern systemd, and pinning APT so only the Firefox package is pulled from Debian unstable #4771. - Move the slim Docker image to Debian trixie (the new stable) and drop the APT pin from #4771, which was too strict to let Firefox's
libc6/libnss3dependencies upgrade from unstable #4772. - CI: allow Docker Hub's CloudFront CDN (
production.cloudfront.docker.com) through the Linux workflow's Harden-Runner egress allowlist, so the test job stops flaking when DNS routes the runner to CloudFront instead of Cloudflare #4773.
v41.2.0
Added
- JS/CSS coverage in the report. Browsertime 27.4.0 collects per-iteration coverage when you pass
--chrome.coverage, and the HTML report now surfaces it as a Coverage section in the per-URL view: median JS/CSS total/unused/percent KPIs, first-party vs third-party split, top-25 worst-offender tables, and a methodology + recommendations panel.--chrome.coverageis declared in sitespeed.io's own CLI so it shows up in--helpand the config reference, and the--enableProfileRunpath now collects coverage on the profile run and merges it into the main result #4769, #4767.
Fixed
- Visual-change lines (
_firstVisualChange/_lastVisualChange/_visualComplete85) are back on the waterfall when the HAR is gzipped on disk (the default). The renderer's user-timing injection was parsing the raw gzip bytes as JSON and silently falling back to the unannotated HAR; it now sniffs the gzip magic bytes and inflates viaDecompressionStreamfirst #4758. - Per-request detail panel on the waterfall now shows real data again. The panel was reading HAR-shape fields (
req.response.content.size,req.response.headers,req.response.status,req.timings, …) but waterfall-tools' click payload is its own flat internalRequestobject, so Response body always showed0 B, Status was blank, MIME type and Protocol were—, and the response-headers and timing tabs were empty. Look up the matching HAR entry by index and read the rich HAR shape from it, falling back to the waterfall-tools shape only when the HAR is missing. - Folder path aliases now accept Unicode letters and digits, so non-ASCII URLs no longer collapse to
-in result paths (issue #3880) #4759. scpplugin: retry the initial SFTP handshake up to 3× with linear backoff.ssh2-sftp-clientv12 removed its built-in connect retries, so a single "Connection lost before handshake" blip was failing the whole upload #4760.- Graphite: retry the post-run annotation POST up to 3× on network errors and 5xx responses. 4xx still fails fast #4761.ß
waterfall-toolsbumped to the first proper npm release, 0.3.0 — no more pinning to a GitHub tarball, and the bundling script drops to ~30 fewer lines now that the published browser bundle has the platform aliases baked in #4764.- Browsertime 27.4.0 #4767.
- Docker base image rev'd to
chrome-148.0-firefox-150.0-edge-147.0-d#4762. - Slim Docker image cleanup #4757.
- Drop now-unused npm
overridesfrompackage.json#4756. - CI: PR Docker workflow now builds and exercises the image on arm64 in addition to amd64, so arch-specific breakage surfaces pre-merge instead of at release-tag time. Edge step is skipped on arm64 (Linux Edge is amd64-only) #4766.
- CI: pin the Safari workflow to
macos-14#4765. - Drop an unnecessary
\.escape inside a character class inpathToFolderthat was tripping eslint'sno-useless-escapeand failing lint on every PR #4763. - Docs: remove unused CSS #4768.
v41.1.0
Added
- New
rsyncplugin for result uploads. The existingscpplugin walks files one at a time over a single SFTP channel, which is the worst case for a result directory of thousands of small files. The new plugin shells out torsyncoverssh, pipelines the wire protocol and reuses the channel — the same upload finishes in a small fraction of the time on a typical Linux host. Exposed as--rsync.host/--rsync.username/--rsync.privateKey/--rsync.destinationPathetc., sitting alongsidescp,s3andgcs; existing scp users keep their exact behaviour and opt in to rsync only when they want it #4739. - Upload performance on the existing
scpplugin: swappednode-scp(serial uploads, stuck on 0.0.25) forssh2-sftp-client, which fans out 16 concurrent uploads on the same ssh2 transport. Same auth, same options, same CLI surface — just faster on result directories with many small files #4738.
Fixed
- Bring back the visual-change markers on the waterfall. The renderer that replaced PerfCascade in #4614 only drew vertical lines for a fixed set of page-event names, so the
_firstVisualChange/_lastVisualChange/_visualComplete85lines silently disappeared with the swap. They're now hoisted into the user-timing-marks bag the renderer does draw, the "Marks & visual metrics" toggle is on by default, and the hover tooltip identifies which metric or user mark the cursor is on #4755. - Browsertime 27.3.0 #4754.
coach-corebumped to 9.2.1 #4750.- Bump
@sitespeed.io/logand the bundled plugin to latest #4746. - Crawler rewrite:
simplecrawler(unmaintained since 2020, ~1000 lines of transitive code) is replaced by an in-treenode:fetch-based crawler in ~285 lines with no new dependency. Same BFS semantics, same depth/maxPages/include/exclude/content-type/skip-extension rules, same robots.txt handling (--crawler.ignoreRobotsTxtstill opts out), same cookies/basicAuth/userAgent passthrough. Parity verified across four real-site runs at different depths and page caps; natural completion is ~6× faster on the sample runs #4745. - Dependency pruning, no behaviour change for users:
lodash.get,lodash.setandlodash.mergeare replaced by small in-tree helpers inlib/support/objectPath.js, with themergereplacement verified byte-for-byte againstlodash.mergeacross 23 edge cases and an A/BparseCommandLine()run.dayjs(plus the utc plugin) is replaced by an ~80-linelib/support/time.js, with every.format()pattern actually used in the codebase pinned in a new test.orais replaced by a ~60-line blinking-dot spinner used only by--api.add/--api.addAndGetResult. The lodash subtree is now gone entirely [#4737, #4741, #4742, #4744, #4740]. - The
markdowntemplate helper exposed to pug templates is removed. It was added in 2018 (#2161) but no shipped.pugtemplate has ever called it, and the underlyingmarkdown@0.5.0package has been unmaintained for over a decade with an open ReDoS advisory. Anyone with a custom pug template that callsmarkdown(...)will need to import their own renderer #4743. - Slimmer main Docker image:
apt-get install --no-install-recommends+/var/lib/apt/listscleanup,npm ci(lockfile-strict) instead ofnpm install, and theselenium-webdriver/bincleanup folded into the install layer so the deleted bytes no longer ship in an earlier layer #4753. - Docker: use
--omit=devinstead of the deprecated--production, and fix theskip edgedrivertypo #4752. - Release tooling: bump
feedto 5.2.1 andmarkedto 18.0.3 (used only byrelease/feed.jswhen refreshing documentation RSS feeds). API usage unchanged, regenerated feeds are content-identical #4751. - Dev tooling: align with eslint 10 and unicorn 64, drop the dead legacy
.eslintrc.jsonand the staleeslint-checkscript, minor bumps to prettier/sass/esbuild #4747.
v41.0.1
v41.0.0
Highlights
A small but breaking release: Node.js 22 is now the minimum, and --help has been redesigned around topic-filtered views instead of dumping every option in one screen.
Breaking
- Node.js 22+ is now required (was Node.js 20+) #4732.
sitespeed.io --helpno longer prints every option from all 26 option groups by default — it now shows a short curated list of common options plus the available topic names. Usesitespeed.io --help <topic>to drill into one topic, orsitespeed.io --help-allto reproduce the historical full dump (kept unchanged for scripts, and used to generate the published docs/config reference) #4730.
Changed
coach-corebumped to 9.1.0, which pulls inpagexray5.0.0 #4731.
Fixed
pagexray 5.0.0 (transitive via coach-core 9.1.0) brings several reporting fixes that show up directly in sitespeed.io output:
- HTTP/3 / HTTP/3.0 connections are now classified as
h3instead of falling through toh1, so the HTTP-version breakdown is correct on HTTP/3 traffic. Cache-Controlis parsed case-insensitively (RFC 7234), soMax-Age=42is read as 42 instead of 0 andNo-Cache/No-Storeare honoured — caching advice andexpireStatsno longer over-report problems on origins that capitalise the directive.missingCompressionno longer flags already-gzipped assets (the encoding check was comparing a flattened header array against a string), accepts compound encodings likebr, gzip, and recogniseszstd.xmlis now also considered for compression reporting.- The
Domain=cookie attribute is matched case-insensitively (RFC 6265), so third-party cookies set with lowercasedomain=are detected. getMainDomainrecognises common two-label public suffixes (.co.jp,.com.br,.com.au, …), so the auto-generated first-party regex stops misclassifying same-site requests on non-.co.ukcountry domains.defaultContentTypesnow includesfavicon, so every page has a consistent shape in the content-type breakdown.getDocumentRequestsreturns an empty array for pages with no matching entries instead of throwing.
v40.5.0
Added
- Scripts are now auto-detected on the command line, so
--multiis no longer required to run them. Any positional argument that looks like a script —.js/.cjs/.mjs, or any file whose first non-empty line doesn't start withhttp— flips multi mode on automatically, and mixed inputs likelogin.js https://example.com logout.jsjust work.--multiis kept as an explicit override for the one case auto-detection can't cover: sharing a single browser session across a list of plain URLs. All existing invocations behave exactly as before #4725.
Fixed
- Gzipped HAR files are now written by piping JSON through
createGzipstraight to disk instead of materialising the JSON string, aBuffercopy of it, and the full gzippedBufferall at once. For a 200 MB HAR that removes several hundred MB of avoidable peak RSS, multiplied when multiple pages finish around the same time. The storage layer now accepts aReadablein addition to strings and Buffers; existing callers are unaffected #4728. - Gzipped JSON result files (Chrome traces, console logs, etc.) are read by streaming through
createGunzipand collecting utf-8 chunks rather than buffering the whole gzipped payload, gunzipping it into another Buffer, then stringifying. The parsed object still has to fit in memory, but the throwaway gzipped and unzipped buffer copies are gone — meaningful on 50+ MB traces #4726. - The sustainable plugin and the S3 plugin pick up the same streaming treatment: the sustainable plugin now uses the shared streaming gzipped-JSON helper instead of its own buffer-everything copy, and the S3 plugin streams uploads via
createReadStreamwith an explicitContentLengthinstead of loading each file fully into memory beforePutObject. With 20 concurrent S3 uploads, RSS no longer spikes to ~20× the size of the largest file in the result bundle #4727.