jimhigson/true-site-size

Measures the real network bytes a browser transfers, from cold cache until your app signals readiness with a performance.mark, and comments the change on pull requests. Captures eager over-loading that file-size diffing cannot see.

View on GitHub

Trust Signals

Scorecard Score
not yet scored
Maintenance Recency
Activelast commit Jul 9, 2026
License
MIT

Pinned Snippet

workflow.ymlSHA-pinned
uses: jimhigson/true-site-size@abc874e538b51932c21720a5f86724a9d1f11db0 # no releases — HEAD as of 2026-07-11

tags can be moved; commit SHAs can't. why a SHA?

namedescriptionrequireddefault
journeyJSON array of steps measuring an interactive journey in one browser session: {goto: url}, {click: selector}, {waitFor: selector}, {waitForGone: selector}, {keys: "Enter ArrowDown"}, {script: "..."}, {row: name, mark: markName}. Each row step closes a measurement segment when its performance.mark fires and the network settles; {row: name, marks: [m1, m2]} waits for all the named marks, for apps whose readiness is several independently-loading parts. A row may carry emoji to badge it in the comment (eg {row: menu, mark: menu-ready, emoji: "🎮"}) instead of the auto-assigned colour circle. {startAgain: name} relaunches the browser cold (empty cache) so one journey can measure several apps served from the same build: rows after it accumulate as a new visit with its own cumulative Σ rows and total; as the journey's first step it just names the first visit. Any step may carry afterMark to await an app readiness mark first. Takes precedence over `scenarios`. ""
ignore-url-patternsJSON array of regex strings. Matching requests are excluded from byte counts (still shown in the run-log breakdown, tagged ignored) - for endpoints whose response size legitimately varies, eg live db reads. []
step-timeout-msper-step timeout, eg waiting for a click target to appear20000
settle-timeout-mshard cap on waiting for the network to go quiet after a mark - if the app never stops requesting (eg endless polling), the row errors with the in-flight urls named rather than hanging 30000
timeout-mshard cap on the entire action (builds and all measurement runs) - a last-resort guard so nothing can hang a ci job indefinitely 900000
scenariossimple form of `journey`: JSON array like [{"name": "menu", "url": "/", "mark": "menu-ready"}], each entry a navigation then a row. Scenarios run in order in one browser session with a shared http cache, so each reports only its incremental bytes. An entry may carry emoji to badge its row in the comment instead of the auto-assigned colour circle. []
install-commandcommand to install dependencies in each checkout (empty to skip)""
build-commandcommand that produces the serveable sitenpm run build
clean-commandcommand run in the workspace between the head and base builds (empty to skip). The base checks out into a worktree inside the workspace, so without this its build can inherit head's node_modules via upward module resolution; eg "pnpm clean" isolates them. ""
serve-dirdirectory (relative to the checkout) to serve after buildingdist
compressionsimulate the production host's compression - gzip, br, zstd or none. zstd requires the runner's Node to be >= 22.15 (or >= 23.8); gzip, br and none work on any supported Node. gzip
compression-levelcompression level for the chosen encoding, or "max" for the codec's maximum. Empty uses a moderate default per codec: gzip 8, br 4, zstd 6. Valid ranges: gzip 0-9, br 0-11, zstd 1-22. Ignored when compression is none. ""
runsrepeat count. Runs are expected to be byte-identical - the extra run is a determinism self-check, and disagreement is flagged on the comment. 2
settle-msms of network quiet required after the mark before stopping1500
mark-timeout-msms to wait for each scenario's performance.mark60000
base-refsJSON array of refs to compare against (defaults to the PR base branch). Each becomes its own column in the comment, linked to the exact commit and annotated with git describe. eg ["main", "v1.4.0"] compares the PR against both main and a release tag. []
commentpost/update a PR comment with the resultstrue
pr-numberPR number to post the comment on. Defaults to the PR that triggered the run; set it to comment from a non-PR event - eg a push to main updating an open release PR's report so it reflects the just-merged code. ""
collapse-breakdowncollapse each ref's per-file breakdown into an expandable <details> (true) or show it inline (false). Rows with no changes are always a plain line, since there is nothing to reveal by expanding. true
measure-diskalso report the total built size on disk - the compressed (as served, matching `compression`) size of every file in serve-dir, loaded or not, with its own changed-files breakdown. Catches shipped-but-unloaded dead weight. Set false to skip compressing the whole site on large builds. true
comment-keydistinguishes multiple uses on one PR - each key maintains its own comment (and is shown in the comment heading) ""
spread-tolerance-bytesbyte spread between repeat runs treated as protocol noise rather than non-determinism (h2 header compression varies slightly with request arrival order). Spread above this triggers the determinism warning. 512
minimum-change-thresholdchanges smaller than this many bytes display as unchanged - same name, semantics and default as compressed-size-action 1
strip-hashregex removed from request filenames so the per-file breakdown matches files across base and head despite content hashes (default matches vite/rollup style "-D4zXn_7K." hashes). Empty string disables. (-[a-zA-Z0-9_-]{8})\.
github-tokentoken used to post the PR comment${{ github.token }}

no outputs