Perf: web client harness on big Homes, with budgets (#327) #360

Closed
kayg wants to merge 1 commit from issue/327-perf-harness into dev
Owner

Part of #327 (web client: make it stupid fast). Measures first; the fixes come as their own PRs.

What

  • perf/web.sh: builds the app, serves it from the real release server (--web) on a fixture Home (10k and 100k notes, kept indexed between runs), and runs apps/web/perf/*.perf.ts with one worker in Chromium (CPU slowed 4x) and WebKit.
  • Tests:
    • boot: cold and warm to the first note painted and the first list row, time to interactive, total blocking time, heap, CLS;
    • typing: keystroke to paint in the 50,000-word note and in a 1,000-item nested list;
    • blaze (#271): flick 50 notes at 100 ms and back, then time to live. Measures missed steps, long tasks, heap and DOM growth, and requests;
    • scroll: frame times in the long note and in All notes;
    • main-thread CPU time from a trace (*_cpu), the number that stays steady on a busy machine.
  • scripts/bundle-size.mjs: raw, gzip and brotli sizes, first paint vs lazy.
  • perf/web-report.mjs: summarises a run and checks web.* budgets with the server harness's rules (metric@N, p50/p95/p50_min, gate: false).
  • Budgets: web.* entries in perf/budgets.json. CI now gates the bundle sizes (perf/web.sh --bundle-only --gate, no server). Browser budgets run with perf/web.sh --gate. Explained in docs/perf/web.md.

No app code changes.

Verified

  • perf/web.sh full run on 10k and 100k, Chromium and WebKit. Baseline numbers are on #327: #327 (comment)
  • perf/web.sh --bundle-only --gate passes (first JS 229 KB brotli, budget 240).
  • bun run check passes, now including apps/web/perf.

🤖 Generated with Claude Code

https://claude.ai/code/session_018Yyy8fQGxPLkLa8v8NXz7T

Part of #327 (web client: make it stupid fast). Measures first; the fixes come as their own PRs. ## What - **`perf/web.sh`**: builds the app, serves it from the real release server (`--web`) on a fixture Home (10k and 100k notes, kept indexed between runs), and runs `apps/web/perf/*.perf.ts` with one worker in Chromium (CPU slowed 4x) and WebKit. - **Tests**: - boot: cold and warm to the first note painted and the first list row, time to interactive, total blocking time, heap, CLS; - typing: keystroke to paint in the 50,000-word note and in a 1,000-item nested list; - **blaze** (#271): flick 50 notes at 100 ms and back, then time to live. Measures missed steps, long tasks, heap and DOM growth, and requests; - scroll: frame times in the long note and in All notes; - main-thread CPU time from a trace (`*_cpu`), the number that stays steady on a busy machine. - **`scripts/bundle-size.mjs`**: raw, gzip and brotli sizes, first paint vs lazy. - **`perf/web-report.mjs`**: summarises a run and checks `web.*` budgets with the server harness's rules (`metric@N`, `p50`/`p95`/`p50_min`, `gate: false`). - **Budgets**: `web.*` entries in perf/budgets.json. CI now gates the bundle sizes (`perf/web.sh --bundle-only --gate`, no server). Browser budgets run with `perf/web.sh --gate`. Explained in **docs/perf/web.md**. No app code changes. ## Verified - `perf/web.sh` full run on 10k and 100k, Chromium and WebKit. Baseline numbers are on #327: https://git.kayg.org/kayg/calternal/issues/327#issuecomment-49280 - `perf/web.sh --bundle-only --gate` passes (first JS 229 KB brotli, budget 240). - `bun run check` passes, now including `apps/web/perf`. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_018Yyy8fQGxPLkLa8v8NXz7T
Perf: a web client harness on big Homes, with budgets (#327)
Some checks failed
CI / server (pull_request) Successful in 22s
CI / rust (pull_request) Successful in 1m49s
CI / web (pull_request) Failing after 2m22s
dd3e19f5b9
perf/web.sh measures the app as production serves it, on the 10k and 100k
fixture Homes, in Chromium (CPU slowed 4x) and WebKit: bundle sizes (raw,
gzip, brotli), cold and warm boot to the first note painted, time to
interactive, keystroke to paint in a 50,000-word note and a 1,000-item
nested list, the blaze test from #271 (flick 50 notes at 100 ms and back),
scroll frame times, long tasks, memory and DOM growth, layout shift, and
the main thread's CPU time (the steady number on a busy machine).

The numbers are checked against new web.* budgets in perf/budgets.json with
the server harness's rules; CI gates the bundle sizes. docs/perf/web.md says
what each metric means and how to run it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018Yyy8fQGxPLkLa8v8NXz7T
Author
Owner

This work is consolidated in PR #508: #508. Closing this superseded PR.

This work is consolidated in PR #508: https://git.kayg.org/kayg/calternal/pulls/508. Closing this superseded PR.
kayg closed this pull request 2026-10-16 17:35:01 +00:00
Some checks failed
CI / server (pull_request) Successful in 22s
CI / rust (pull_request) Successful in 1m49s
CI / web (pull_request) Failing after 2m22s

Pull request closed

Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
kayg/calternal!360
No description provided.