Skip to content

ci: enforce a 250 KB gzip JS budget per page - #10

Merged
TheSeydiCharyyev merged 3 commits into
Shapak-Apps:mainfrom
aynazar-sylyyew-dev:feature/check-size-limit
Sep 29, 2026
Merged

TheSeydiCharyyev merged 3 commits into
Shapak-Apps:mainfrom
aynazar-sylyyew-dev:feature/check-size-limit

Conversation

@aynazar-sylyyew-dev

@aynazar-sylyyew-dev aynazar-sylyyew-dev commented Sep 29, 2026 •

Copy link
Copy Markdown
Member

Closes #6 (hard CI budget for JS shipped per page).

What changed

  • scripts/check-size.mjs — new CI script, Node built-ins only (node:fs, node:zlib, node:path), zero new dependencies.
    • Recursively finds every index.html in out/.
    • Extracts every <script src="/_next/…"> the page loads (deduped).
    • Sums zlib.gzipSync sizes of those files and prints a per-page table (page, KB gzip).
    • Exits with code 1 if any page exceeds the budget. The budget is a single constant LIMIT_KB at the top of the file.
  • package.json — adds "check:size": "node scripts/check-size.mjs".
  • .github/workflows/deploy.yml — runs npm run check:size after npm run build and the store-pages check, before upload-pages-artifact. An over-budget build fails the build job and never reaches deployment; every PR to main gets the check.

Current numbers (static export, Next.js 16.3.6)

Page KB gzip
/ 173.21
/ru/ 173.21
/en/ 173.21
/projects/ 173.54
/ru/projects/ 173.54
/en/projects/ 173.54
/404/, /_not-found/ 169.39

All pages are ~174 KB today, so the 250 KB budget passes with ~76 KB of headroom for the upcoming animations work.

Proof the check actually fails

  • Commit 95e3d8d sets LIMIT_KB = 100 → its CI run is red: all 8 pages (~173 KB) exceed the budget and the build job fails at the "Check bundle size limit" step.
  • Commit 87644e8 restores LIMIT_KB = 250 → CI is green again.
    Both runs are visible in the Checks timeline and in the Actions tab.

Why

Internet in Turkmenistan is slow and expensive. The old site shipped ~3 KB of JS; the Next.js migration took that to ~174 KB per page. A hard, CI-enforced budget prevents further silent growth (animations are next).

@TheSeydiCharyyev TheSeydiCharyyev left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Checked 87644c8 locally and in CI. The table matches my build (173.21 / 173.54 KB), the 100 KB commit is red, the 250 KB head is green, and the step runs before the upload. Good.

Two things before merge:

  1. A missing script is counted as 0 KB (getGzipSize catches the error and returns 0). I deleted one 28.9 KB chunk that / loads and ran the script: it printed 165.78 KB for / and exited with code 0. A budget check must not pass with a lower number when a file is missing. Please remove the try/catch there, and if a /_next/ file that a page references does not exist, print the page and the file and exit with code 1. Also match src.startsWith('/_next/') instead of src.includes('/_next/'), so a full URL is never mapped to a local path.

  2. Please remove "start": "next start" from package.json. It is not part of #6, and it does not work with our static export: npm start fails with "next start" does not work with "output: export" configuration.

Small thing: deploy.yml now ends with a line of spaces and no newline. Please remove that line.

@aynazar-sylyyew-dev

Copy link
Copy Markdown
Member Author

All three points addressed in the new commit:

  • getGzipSize no longer swallows errors. A referenced /_next/ file that does not exist is printed as page <route> -> <path> and the check exits 1 (verified locally by renaming a chunk: the page is flagged in the table and the run fails).
  • Src matching is now src.startsWith('/_next/'), so absolute URLs are never mapped into out/.
  • "start": "next start" removed from package.json.
  • deploy.yml no longer ends with a spaces-only line; the file now ends with a single newline.

@TheSeydiCharyyev TheSeydiCharyyev left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Checked 7703086. I deleted the same 28.9 KB chunk again: the script now marks every page with "1 missing", lists page -> file, and exits with code 1. On a normal build it passes with 173.21 / 173.54 KB. next start is gone and deploy.yml ends with one newline. CI is green.

Tiny and optional: "scripts": { in package.json is indented with 4 spaces, the rest of the file uses 2.

@TheSeydiCharyyev
TheSeydiCharyyev merged commit 8225534 into Shapak-Apps:main Sep 29, 2026
2 checks passed
@aynazar-sylyyew-dev
aynazar-sylyyew-dev deleted the feature/check-size-limit branch September 29, 2026 06:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Fail the build when a page ships more than 250 KB of JavaScript

2 participants