Calendar scroll: Intl formatter and scroll-restoration cost per fling #1461

Closed
opened 2026-10-08 12:32:02 +00:00 by kayg · 32 comments
Owner

Problem

Calendar scroll traces on the perf VM (#1362, worktree calscroll-1362) show the device-time-zone Intl.DateTimeFormat helper costing 147 ms in one Week/390 fling and 45 ms in Day/1440; SvelteKit scroll-position/restoration helpers cost 95–134 ms; getBoundingClientRect under Svelte animation measurement 71 ms. Phone Day/Week still show 27/18 blank frames over six flings.

Work

  1. Cache Intl.DateTimeFormat/NumberFormat instances per (locale, zone, options) app-wide in one shared helper (search for existing formatters; one owner). No per-cell/per-row construction.
  2. Find why SvelteKit scroll restoration runs during in-page Calendar scrolling (likely replaceState/goto on scroll or date change) and stop it from running per frame.
  3. Remove layout reads during scroll animations in Calendar grid components.
    Measure on the macOS test VM in real Chrome (calternal@10.69.69.21 via netbird ssh; reverse-tunnel the local server) AND on the perf VM, interleaved vs origin/dev: blank frames, long frames, card-paint p95 for Day/Week at 390 and 1440. Gates: bun run check, bun run test --maxWorkers=2; quote verbatim.
## Problem Calendar scroll traces on the perf VM (#1362, worktree calscroll-1362) show the device-time-zone `Intl.DateTimeFormat` helper costing 147 ms in one Week/390 fling and 45 ms in Day/1440; SvelteKit scroll-position/restoration helpers cost 95–134 ms; `getBoundingClientRect` under Svelte animation measurement 71 ms. Phone Day/Week still show 27/18 blank frames over six flings. ## Work 1. Cache Intl.DateTimeFormat/NumberFormat instances per (locale, zone, options) app-wide in one shared helper (search for existing formatters; one owner). No per-cell/per-row construction. 2. Find why SvelteKit scroll restoration runs during in-page Calendar scrolling (likely replaceState/goto on scroll or date change) and stop it from running per frame. 3. Remove layout reads during scroll animations in Calendar grid components. Measure on the macOS test VM in real Chrome (calternal@10.69.69.21 via netbird ssh; reverse-tunnel the local server) AND on the perf VM, interleaved vs origin/dev: blank frames, long frames, card-paint p95 for Day/Week at 390 and 1440. Gates: bun run check, bun run test --maxWorkers=2; quote verbatim.
Author
Owner

Starting work on branch job/intlfmt-1461, based on job/calscroll-1362 at 6c508d4d7f0361d764ad77cd3a740ef762779dce. I have read the repository contract, Calendar design sections, and glossary. I am tracing shared date formatting, route state writes during grid scrolling, and animation measurement in the Calendar grids before making focused commits.

Starting work on branch `job/intlfmt-1461`, based on `job/calscroll-1362` at `6c508d4d7f0361d764ad77cd3a740ef762779dce`. I have read the repository contract, Calendar design sections, and glossary. I am tracing shared date formatting, route state writes during grid scrolling, and animation measurement in the Calendar grids before making focused commits.
Author
Owner

Finding: the Calendar scroll settle callback (onGridSettle) calls syncWindowUrl, which uses goto(..., { replaceState: true, noScroll: true }). Each such route navigation reaches the root beforeNavigate/afterNavigate handlers in +layout.svelte, which save and restore the route feed offset. The update is one call per settled fling, not one per scroll frame. I will make this same-entry date update shallow so SvelteKit does not run route scroll restoration for it.

The shared UI already memoizes date and number formatters, but systemTimeZone() still calls Intl.DateTimeFormat() on every call. formatHour() calls it unless a zone is supplied. There are also direct Intl.NumberFormat constructions in app modules. I will route these through the shared formatter owner and test constructor reuse.

Finding: the Calendar scroll settle callback (`onGridSettle`) calls `syncWindowUrl`, which uses `goto(..., { replaceState: true, noScroll: true })`. Each such route navigation reaches the root `beforeNavigate`/`afterNavigate` handlers in `+layout.svelte`, which save and restore the route feed offset. The update is one call per settled fling, not one per scroll frame. I will make this same-entry date update shallow so SvelteKit does not run route scroll restoration for it. The shared UI already memoizes date and number formatters, but `systemTimeZone()` still calls `Intl.DateTimeFormat()` on every call. `formatHour()` calls it unless a zone is supplied. There are also direct `Intl.NumberFormat` constructions in app modules. I will route these through the shared formatter owner and test constructor reuse.
Author
Owner

Finding and implementation: the settled-grid callback used the app's goto wrapper with replaceState: true. Although this ran once after each settle rather than on every raw scroll frame, it still entered SvelteKit's route lifecycle and the shell's feed-offset save/restore hooks. Calendar date and view now come from the current URL through parseCalendarRoute; the helper extends the existing Calendar deep-link model and is shared with the sidebar. Settled and focused same-page updates now use SvelteKit shallow replaceState, preserving the current history state without running route navigation or scroll restoration. The focused route tests pass: 2 tests.

Decision not stated in DESIGN: use packages/ui's Calendar model as the single owner of the /calendar/{view}/{date} grammar, and derive the live Calendar selection from page.url because shallow routing leaves load data unchanged.

Finding and implementation: the settled-grid callback used the app's `goto` wrapper with `replaceState: true`. Although this ran once after each settle rather than on every raw scroll frame, it still entered SvelteKit's route lifecycle and the shell's feed-offset save/restore hooks. Calendar date and view now come from the current URL through `parseCalendarRoute`; the helper extends the existing Calendar deep-link model and is shared with the sidebar. Settled and focused same-page updates now use SvelteKit shallow `replaceState`, preserving the current history state without running route navigation or scroll restoration. The focused route tests pass: 2 tests. Decision not stated in DESIGN: use `packages/ui`'s Calendar model as the single owner of the `/calendar/{view}/{date}` grammar, and derive the live Calendar selection from `page.url` because shallow routing leaves load data unchanged.
Author
Owner

Finding and correction: the new profile passed its release binary and forwarded port to startServer, but the imported helper from calendar-perf.mjs ignored both options and always started the debug binary on a random port. I switched the profile to the shared harness.mjs server helper, which honors both options and cleans up its temporary data asynchronously. The profile now dismisses the known build-update notice before sampling so it cannot affect measured interactions. node --check apps/web/e2e/calendar-scroll-1362.mjs and git diff --check pass.

Finding and correction: the new profile passed its release binary and forwarded port to `startServer`, but the imported helper from `calendar-perf.mjs` ignored both options and always started the debug binary on a random port. I switched the profile to the shared `harness.mjs` server helper, which honors both options and cleans up its temporary data asynchronously. The profile now dismisses the known build-update notice before sampling so it cannot affect measured interactions. `node --check apps/web/e2e/calendar-scroll-1362.mjs` and `git diff --check` pass.
Author
Owner

Finding: an attached Chrome profile is reused for interleaved origin/current runs. Reusing its default browser context would carry cookies and local preferences from one temporary server into the next. The profile now creates and closes a fresh browser context for each phase while keeping the same real Chrome process, so A/B measurements start with isolated browser storage. node --check apps/web/e2e/calendar-scroll-1362.mjs and git diff --check pass.

Finding: an attached Chrome profile is reused for interleaved origin/current runs. Reusing its default browser context would carry cookies and local preferences from one temporary server into the next. The profile now creates and closes a fresh browser context for each phase while keeping the same real Chrome process, so A/B measurements start with isolated browser storage. `node --check apps/web/e2e/calendar-scroll-1362.mjs` and `git diff --check` pass.
Author
Owner

Runner update: the profile now accepts CALTERNAL_PROFILE_TIMEZONE and records it in the JSON report. UTC remains the deterministic default; Mac runs can select Europe/Berlin so the device-time-zone formatter path is exercised with the Mac profile's zone. node --check apps/web/e2e/calendar-scroll-1362.mjs and git diff --check pass.

Runner update: the profile now accepts `CALTERNAL_PROFILE_TIMEZONE` and records it in the JSON report. UTC remains the deterministic default; Mac runs can select `Europe/Berlin` so the device-time-zone formatter path is exercised with the Mac profile's zone. `node --check apps/web/e2e/calendar-scroll-1362.mjs` and `git diff --check` pass.
Author
Owner

Runner update: each scroll result now reports both frames over 16.7 ms and frames over 50 ms. This keeps dropped display frames separate from longer stalls for the requested comparison. node --check apps/web/e2e/calendar-scroll-1362.mjs and git diff --check pass.

Runner update: each scroll result now reports both frames over 16.7 ms and frames over 50 ms. This keeps dropped display frames separate from longer stalls for the requested comparison. `node --check apps/web/e2e/calendar-scroll-1362.mjs` and `git diff --check` pass.
Author
Owner

Perf VM baseline A1 completed under perf-run on origin/dev (af202e1514955ddf0f8b4b3d2503c780d807ed84) with the matching release server and Chromium 153. The real fixture had 84 days, 1,680 Events, 84 Tasks and 84 Logs; CPU throttle was 4×. The fast-prefetch check passed with 0 blank frames. Across the two wheel directions per cell: Day/390 had 0 blank-range frames and 19 frames over 50 ms; Week/390 had 7 and 23; Day/1440 had 0 and 28; Week/1440 had 0 and 31. The Week/1440 forward trace recorded 352 getBoundingClientRect samples under Svelte's measure, 2,328.86 ms in Layout and 1,731.81 ms in UpdateLayoutTree. Load average inside the locked run was [2.14, 1.16, 2.20] before sampling and [2.57, 2.06, 2.34] after. This is one baseline profile; the interleaved branch and Mac runs are still pending.

Perf VM baseline A1 completed under `perf-run` on `origin/dev` (`af202e1514955ddf0f8b4b3d2503c780d807ed84`) with the matching release server and Chromium 153. The real fixture had 84 days, 1,680 Events, 84 Tasks and 84 Logs; CPU throttle was 4×. The fast-prefetch check passed with 0 blank frames. Across the two wheel directions per cell: Day/390 had 0 blank-range frames and 19 frames over 50 ms; Week/390 had 7 and 23; Day/1440 had 0 and 28; Week/1440 had 0 and 31. The Week/1440 forward trace recorded 352 `getBoundingClientRect` samples under Svelte's `measure`, 2,328.86 ms in Layout and 1,731.81 ms in UpdateLayoutTree. Load average inside the locked run was `[2.14, 1.16, 2.20]` before sampling and `[2.57, 2.06, 2.34]` after. This is one baseline profile; the interleaved branch and Mac runs are still pending.
Author
Owner

Mac Chrome smoke test confirmed connectOverCDP and a fresh browser context work on Chrome 154. The first profile attempt then failed before fixture setup because the runner applied locale/timezone in browser.newContext() and repeated the same CDP emulation commands; Chrome returned Another locale override is already in effect. I removed the duplicate CDP calls. The context options still apply en-GB and the selected profile zone. node --check and git diff --check pass.

Mac Chrome smoke test confirmed `connectOverCDP` and a fresh browser context work on Chrome 154. The first profile attempt then failed before fixture setup because the runner applied locale/timezone in `browser.newContext()` and repeated the same CDP emulation commands; Chrome returned `Another locale override is already in effect`. I removed the duplicate CDP calls. The context options still apply `en-GB` and the selected profile zone. `node --check` and `git diff --check` pass.
Author
Owner

Mac evidence update: Chrome 154 on the private macOS profile reached the Day/390 light and dark mid-fling and settled screenshots. Before Week/390 finished, Playwright reported Target page, context or browser has been closed; the NetBird SSH session had also ended and released /tmp/mac-bench.lock. This attempt therefore has no complete Mac metric JSON and its partial captures are not a complete screenshot set. A prior local-runtime lookup issue is fixed by reusing the already-built runtime at /home/kayg/Developer/calternal-wt/adv31/target/e2e-media-runtime. I will retry in shorter viewport/view slices and keep the SSH foreground loop emitting heartbeats. The VM is now in use by another job, so I am waiting for its lock before retrying.

Mac evidence update: Chrome 154 on the private macOS profile reached the Day/390 light and dark mid-fling and settled screenshots. Before Week/390 finished, Playwright reported `Target page, context or browser has been closed`; the NetBird SSH session had also ended and released `/tmp/mac-bench.lock`. This attempt therefore has no complete Mac metric JSON and its partial captures are not a complete screenshot set. A prior local-runtime lookup issue is fixed by reusing the already-built runtime at `/home/kayg/Developer/calternal-wt/adv31/target/e2e-media-runtime`. I will retry in shorter viewport/view slices and keep the SSH foreground loop emitting heartbeats. The VM is now in use by another job, so I am waiting for its lock before retrying.
Author
Owner

The full web gate exposed a system-zone cache regression: process.env.TZ changes between Node Calendar cases, but the new app-wide cached systemTimeZone() kept the first detected value. This caused 14 failures in src/lib/calendar/zones.test.ts (day keys and Log instants); existing assertions were kept unchanged. The cache now refreshes only when the Node TZ setting changes, so ordinary Calendar reads do not construct an Intl formatter. Added a direct regression test. Focused verification: Test Files 2 passed (2); Tests 50 passed (50) for src/lib/calendar/zones.test.ts and src/lib/time.test.ts.

The full web gate exposed a system-zone cache regression: `process.env.TZ` changes between Node Calendar cases, but the new app-wide cached `systemTimeZone()` kept the first detected value. This caused 14 failures in `src/lib/calendar/zones.test.ts` (day keys and Log instants); existing assertions were kept unchanged. The cache now refreshes only when the Node `TZ` setting changes, so ordinary Calendar reads do not construct an Intl formatter. Added a direct regression test. Focused verification: `Test Files 2 passed (2); Tests 50 passed (50)` for `src/lib/calendar/zones.test.ts` and `src/lib/time.test.ts`.
Author
Owner

The full web test gate initially found a zone-cache regression. I kept the old expectations, changed systemTimeZone() to invalidate only when Node's TZ setting changes, and added a direct regression case. The focused zone/time suites passed (2 files, 50 tests). Final gates after the fix:

bun run check: perf-lint: PASS; 0 violations; 22544 scoped exceptions; svelte-check found 0 errors and 4 warnings in 2 files.

bun run test --maxWorkers=2: Test Files 298 passed (298); Tests 2128 passed (2128); Duration 634.74s (transform 27%, environment 27%, import 22%, tests 17%, setup 6%).

The production web build completed with client build ID af202e1514955ddf0f8b4b3d2503c780d807ed84, matching the shared origin/dev server build.

The full web test gate initially found a zone-cache regression. I kept the old expectations, changed `systemTimeZone()` to invalidate only when Node's `TZ` setting changes, and added a direct regression case. The focused zone/time suites passed (2 files, 50 tests). Final gates after the fix: `bun run check`: `perf-lint: PASS; 0 violations; 22544 scoped exceptions`; `svelte-check found 0 errors and 4 warnings in 2 files`. `bun run test --maxWorkers=2`: `Test Files 298 passed (298)`; `Tests 2128 passed (2128)`; `Duration 634.74s (transform 27%, environment 27%, import 22%, tests 17%, setup 6%)`. The production web build completed with client build ID `af202e1514955ddf0f8b4b3d2503c780d807ed84`, matching the shared `origin/dev` server build.
Author
Owner

Perf VM current-branch trace finding: Week/1440 week-forward-trace-after.cpu.json contains 586 getBoundingClientRect samples below Svelte's measure in BIPLcumV.js. The Calendar view switcher uses shared SegmentedControl; that primitive puts animate:flip on every option and passes a zero duration when reorder animation is off. The Svelte runtime still snapshots each option's box on updates. I am changing the shared primitive to omit the animation directive unless keyed tab reordering is enabled, and adding a component regression test. The trace and metrics were recorded under perf-run's lock; B1 used the 84-day/1,680-Event fixture and passed its first-prefetched-range assertion with 0 blank frames.

Perf VM current-branch trace finding: Week/1440 `week-forward-trace-after.cpu.json` contains 586 `getBoundingClientRect` samples below Svelte's `measure` in `BIPLcumV.js`. The Calendar view switcher uses shared `SegmentedControl`; that primitive puts `animate:flip` on every option and passes a zero duration when reorder animation is off. The Svelte runtime still snapshots each option's box on updates. I am changing the shared primitive to omit the animation directive unless keyed tab reordering is enabled, and adding a component regression test. The trace and metrics were recorded under `perf-run`'s lock; B1 used the 84-day/1,680-Event fixture and passed its first-prefetched-range assertion with 0 blank frames.
Author
Owner

B1 trace review found 586 getBoundingClientRect samples under Svelte's animate:flip measure() during Calendar scrolling. SegmentedControl now uses the shared captureRects/flipGroup helper only when keyed option IDs change order; same-order updates skip button geometry reads. The focused regression suite passes (2 tests). Updated only the exact SegmentedControl source hashes in the existing perf exception/adoption pins; the original rules and limits are unchanged.

B1 trace review found 586 getBoundingClientRect samples under Svelte's animate:flip measure() during Calendar scrolling. SegmentedControl now uses the shared captureRects/flipGroup helper only when keyed option IDs change order; same-order updates skip button geometry reads. The focused regression suite passes (2 tests). Updated only the exact SegmentedControl source hashes in the existing perf exception/adoption pins; the original rules and limits are unchanged.
Author
Owner

Mac A2 setup surfaced a build identity mismatch: the shared release server reports build_id cc1af3c12b, while the origin/dev web asset reported af202e1514. I’m rebuilding both web artifacts with the server’s build ID and will discard A2 for the interleaved comparison; this keeps the screenshot/update-notice check valid.

Mac A2 setup surfaced a build identity mismatch: the shared release server reports build_id cc1af3c12b68ad26c8403adde1be39c096b9ddea, while the origin/dev web asset reported af202e1514955ddf0f8b4b3d2503c780d807ed84. I’m rebuilding both web artifacts with the server’s build ID and will discard A2 for the interleaved comparison; this keeps the screenshot/update-notice check valid.
Author
Owner

Matched-build Mac A3 baseline, Europe/Berlin, 4x CPU: the synchronous first-prefetch range painted in 0 ms, but the prefetch probe recorded 3 blank frames in one later 2026-10-26–11-01 range at 390 px (84 days / 1,680 Events / 84 Tasks / 84 Logs). The baseline run is continuing through 1440 px; I’ll compare the branch result against this.

Matched-build Mac A3 baseline, Europe/Berlin, 4x CPU: the synchronous first-prefetch range painted in 0 ms, but the prefetch probe recorded 3 blank frames in one later 2026-10-26–11-01 range at 390 px (84 days / 1,680 Events / 84 Tasks / 84 Logs). The baseline run is continuing through 1440 px; I’ll compare the branch result against this.
Author
Owner

Mac Chrome comparison (8 October 2026; Chrome 154; Europe/Berlin; 84 days, 1,680 events, 84 tasks, 84 logs; 4x CPU throttle). Origin/dev A3 and branch B2 served matching web/server build IDs (cc1af3c12b68ad26c8403adde1be39c096b9ddea).

  • The origin/dev prefetch probe recorded 3 blank frames for the 26 October–1 November range. Branch B2 recorded 0 blank frames and passed the first-frame prefetch assertion (9 requests in that probe).
  • Aggregate frames over 50 ms across four gestures per view: at 390 px, Day/Week were 84/81 on origin/dev and 94/100 on the branch; at 1440 px, Day/Week were 89/83 on origin/dev and 73/70 on the branch. Card-paint p95 was 0 ms for all four views and widths.
  • The profile host load averages before A3 and B2 were 26.23/24.56/20.69 and 35.51/30.87/24.70. This makes frame-count comparison load-confounded; I do not claim a phone frame-count improvement from this run.

Measurement data: artifacts/intlfmt-1461/mac-A3.json and artifacts/intlfmt-1461/mac-B2.json. Phone and desktop screenshots are captured. The separate tablet capture timed out on a theme switch and is being retried. Perf VM comparison remains pending.

Mac Chrome comparison (8 October 2026; Chrome 154; Europe/Berlin; 84 days, 1,680 events, 84 tasks, 84 logs; 4x CPU throttle). Origin/dev A3 and branch B2 served matching web/server build IDs (`cc1af3c12b68ad26c8403adde1be39c096b9ddea`). - The origin/dev prefetch probe recorded 3 blank frames for the 26 October–1 November range. Branch B2 recorded 0 blank frames and passed the first-frame prefetch assertion (9 requests in that probe). - Aggregate frames over 50 ms across four gestures per view: at 390 px, Day/Week were 84/81 on origin/dev and 94/100 on the branch; at 1440 px, Day/Week were 89/83 on origin/dev and 73/70 on the branch. Card-paint p95 was 0 ms for all four views and widths. - The profile host load averages before A3 and B2 were 26.23/24.56/20.69 and 35.51/30.87/24.70. This makes frame-count comparison load-confounded; I do not claim a phone frame-count improvement from this run. Measurement data: `artifacts/intlfmt-1461/mac-A3.json` and `artifacts/intlfmt-1461/mac-B2.json`. Phone and desktop screenshots are captured. The separate tablet capture timed out on a theme switch and is being retried. Perf VM comparison remains pending.
Author
Owner

Mac Chrome 154 production-build screenshots for issue #1461. Day and Week cards were present, capture notices were cleared, and the client/server build IDs matched (cc1af3c12b68ad26c8403adde1be39c096b9ddea). Each image is a real Mac capture at its original viewport size.

The tablet screenshots are pending the shared Mac VM lease and will be added in a follow-up.

Day · 390 px

Light
Day 390 px, light theme
Dark
Day 390 px, dark theme

Week · 390 px

Light
Week 390 px, light theme
Dark
Week 390 px, dark theme

Day · 1440 px

Light
Day 1440 px, light theme
Dark
Day 1440 px, dark theme

Week · 1440 px

Light
Week 1440 px, light theme
Dark
Week 1440 px, dark theme

Mac Chrome 154 production-build screenshots for issue #1461. Day and Week cards were present, capture notices were cleared, and the client/server build IDs matched (`cc1af3c12b68ad26c8403adde1be39c096b9ddea`). Each image is a real Mac capture at its original viewport size. The tablet screenshots are pending the shared Mac VM lease and will be added in a follow-up. ### Day · 390 px **Light** ![Day 390 px, light theme](https://git.kayg.org/attachments/6a0422fd-fd6c-45aa-9ba3-a76fecbd027a) **Dark** ![Day 390 px, dark theme](https://git.kayg.org/attachments/2e45c888-b0ff-49c9-84b1-7f6f3a7858c5) ### Week · 390 px **Light** ![Week 390 px, light theme](https://git.kayg.org/attachments/89f7110d-b1ce-44f0-909e-9978a7742270) **Dark** ![Week 390 px, dark theme](https://git.kayg.org/attachments/d243ef76-11f8-4c6f-a216-72216c138377) ### Day · 1440 px **Light** ![Day 1440 px, light theme](https://git.kayg.org/attachments/a2591d38-ad0f-4a2a-b94e-083393b51a0c) **Dark** ![Day 1440 px, dark theme](https://git.kayg.org/attachments/546df73a-89ac-4175-9f86-36a86b9ea6fc) ### Week · 1440 px **Light** ![Week 1440 px, light theme](https://git.kayg.org/attachments/4bed6c3f-7caf-4a07-b3e8-2aa765663322) **Dark** ![Week 1440 px, dark theme](https://git.kayg.org/attachments/0a3f44d4-cf49-4902-80d5-1fc5e61bef01)
Author
Owner

Mac Chrome screenshots at 820 px are attached (Day and Week, light and dark). The 820 px profile completed with regression.passed=true, blank_frames=0, and matching branch web/server build IDs. The runner timed out only during its optional extra 390 px screenshot retry, after the requested 820 px captures and profile had been saved.

Day light 820px

Day dark 820px

Week light 820px

Week dark 820px

Mac Chrome screenshots at 820 px are attached (Day and Week, light and dark). The 820 px profile completed with `regression.passed=true`, `blank_frames=0`, and matching branch web/server build IDs. The runner timed out only during its optional extra 390 px screenshot retry, after the requested 820 px captures and profile had been saved. ![Day light 820px](https://git.kayg.org/attachments/b1824d6f-1fc4-4775-9e17-8b04c179e7a8) ![Day dark 820px](https://git.kayg.org/attachments/89a91080-eabe-44a2-ba27-0c9fde51ecde) ![Week light 820px](https://git.kayg.org/attachments/ea2b62d9-73eb-4809-beea-a07b419b019b) ![Week dark 820px](https://git.kayg.org/attachments/5213a1c9-38ac-435a-bfc0-730c673ca001)
Author
Owner

Mac profile metric clarification: the earlier “3 blank frames → 0” refers only to the separate first-prefetched-Week-range probe (regression.blank_frames). Summing the scroll-profile blank_range_frames across its four runs per cell gives the table below. Card-paint p95 is the value emitted by the profile; it was 0 ms in every cell.

Width View A3 blank B2 blank A3 frames >50 ms B2 frames >50 ms A3/B2 card-paint p95
390 px Day 0 0 84 94 0 / 0 ms
390 px Week 7 5 81 100 0 / 0 ms
1440 px Day 0 0 89 73 0 / 0 ms
1440 px Week 0 0 83 70 0 / 0 ms

A3 and B2 Mac runs were load-confounded: the host load averages before the profiles were [26.23, 24.56, 20.69] and [35.51, 30.87, 24.70]. I do not infer a phone long-frame improvement from these runs. The perf VM A/B is queued under its shared lease.

Mac profile metric clarification: the earlier “3 blank frames → 0” refers only to the separate first-prefetched-Week-range probe (`regression.blank_frames`). Summing the scroll-profile `blank_range_frames` across its four runs per cell gives the table below. Card-paint p95 is the value emitted by the profile; it was 0 ms in every cell. | Width | View | A3 blank | B2 blank | A3 frames >50 ms | B2 frames >50 ms | A3/B2 card-paint p95 | | --- | --- | ---: | ---: | ---: | ---: | --- | | 390 px | Day | 0 | 0 | 84 | 94 | 0 / 0 ms | | 390 px | Week | 7 | 5 | 81 | 100 | 0 / 0 ms | | 1440 px | Day | 0 | 0 | 89 | 73 | 0 / 0 ms | | 1440 px | Week | 0 | 0 | 83 | 70 | 0 / 0 ms | A3 and B2 Mac runs were load-confounded: the host load averages before the profiles were `[26.23, 24.56, 20.69]` and `[35.51, 30.87, 24.70]`. I do not infer a phone long-frame improvement from these runs. The perf VM A/B is queued under its shared lease.
Author
Owner

Perf VM origin/dev A2 is complete. Chrome 153 on the perf VM ran at 4× CPU throttle with UTC and the 84-day / 1,680-event, 84-task, 84-log fixture. Client and release-server build IDs matched (cc1af3c12b68ad26c8403adde1be39c096b9ddea). The first-prefetched Week probe passed: 0 ms paint delay, 0 blank frames, 12 requests.

Each cell below sums four scroll runs. “Long” counts frames over 50 ms; card-paint p95 is the maximum emitted per-run p95.

Width View Blank frames Long frames Card-paint p95
390 px Day 0 35 0 ms
390 px Week 8 39 221.63 ms
1440 px Day 0 48 0 ms
1440 px Week 0 47 0 ms

The perf VM load averages sampled inside the lease were 4.09 / 3.71 / 3.43 at start and 2.08 / 2.71 / 3.06 at end. The local API-server/driver host was busier: its profile load average moved from 5.81 / 11.50 / 16.65 to 3.92 / 8.73 / 14.95, so response-dependent card-paint timing may be affected. Full JSON is retained locally at artifacts/intlfmt-1461/perf-A2.json; branch B2 is queued for the next lease.

Perf VM origin/dev A2 is complete. Chrome 153 on the perf VM ran at 4× CPU throttle with UTC and the 84-day / 1,680-event, 84-task, 84-log fixture. Client and release-server build IDs matched (`cc1af3c12b68ad26c8403adde1be39c096b9ddea`). The first-prefetched Week probe passed: 0 ms paint delay, 0 blank frames, 12 requests. Each cell below sums four scroll runs. “Long” counts frames over 50 ms; card-paint p95 is the maximum emitted per-run p95. | Width | View | Blank frames | Long frames | Card-paint p95 | | --- | --- | ---: | ---: | ---: | | 390 px | Day | 0 | 35 | 0 ms | | 390 px | Week | 8 | 39 | 221.63 ms | | 1440 px | Day | 0 | 48 | 0 ms | | 1440 px | Week | 0 | 47 | 0 ms | The perf VM load averages sampled inside the lease were 4.09 / 3.71 / 3.43 at start and 2.08 / 2.71 / 3.06 at end. The local API-server/driver host was busier: its profile load average moved from 5.81 / 11.50 / 16.65 to 3.92 / 8.73 / 14.95, so response-dependent card-paint timing may be affected. Full JSON is retained locally at `artifacts/intlfmt-1461/perf-A2.json`; branch B2 is queued for the next lease.
Author
Owner

Perf VM branch B2 is complete. Its first-prefetched Week probe passed (0 ms paint delay, 0 blank frames), but the scroll profile was mixed. At 390 px Week, four runs recorded 23 blank-range frames and 500 ms maximum card-paint p95, compared with A2's 8 blank-range frames and 221.63 ms. Branch B2 also started more API requests during the profile than A2. The local API-server/driver host was much busier in B2 (load average 28.16 / 15.58 / 16.14 before and 28.86 / 21.27 / 18.23 after), so the card/blank comparison is not causal.

Source inspection found that date is derived from page.url, while the URL-driven $effect calls load(view, date, ...) for every date change. syncWindowUrl marks its own shallow updates in selfNavigated, but the load effect does not consult that set. I am adding a guard so an own date-only sync does not start another Calendar load; view or filter changes still load normally. The current B2 result is retained as evidence, and I will recheck the branch after the fix.

Perf VM branch B2 is complete. Its first-prefetched Week probe passed (0 ms paint delay, 0 blank frames), but the scroll profile was mixed. At 390 px Week, four runs recorded 23 blank-range frames and 500 ms maximum card-paint p95, compared with A2's 8 blank-range frames and 221.63 ms. Branch B2 also started more API requests during the profile than A2. The local API-server/driver host was much busier in B2 (load average 28.16 / 15.58 / 16.14 before and 28.86 / 21.27 / 18.23 after), so the card/blank comparison is not causal. Source inspection found that `date` is derived from `page.url`, while the URL-driven `$effect` calls `load(view, date, ...)` for every date change. `syncWindowUrl` marks its own shallow updates in `selfNavigated`, but the load effect does not consult that set. I am adding a guard so an own date-only sync does not start another Calendar load; view or filter changes still load normally. The current B2 result is retained as evidence, and I will recheck the branch after the fix.
Author
Owner

The self-sync load guard is now profiled on the branch (B3, revision 0d2f38f33). The first-prefetched Week probe passed: 0 ms paint delay and 0 blank frames. Its request counter was 15, down from B2's 27. Across the four Day/Week scroll runs per cell, 390 px Week fell from B2's 23 blank-range frames / 500 ms card-paint p95 to 10 / 133.3 ms. The origin/dev A2 cell was 8 / 221.63 ms, so the final phone result does not show a clear win over A2.

Width View A2 blank / >50 ms / card p95 B3 blank / >50 ms / card p95
390 px Day 0 / 35 / 0 ms 0 / 40 / 0 ms
390 px Week 8 / 39 / 221.63 ms 10 / 42 / 133.3 ms
1440 px Day 0 / 48 / 0 ms 0 / 54 / 0 ms
1440 px Week 0 / 47 / 0 ms 0 / 50 / 0 ms

The API request totals across all 16 gestures were A2 79, B2 171 and B3 137. The B3 local API-server/driver host load was high (21.27 / 20.71 / 21.03 before, 31.37 / 23.76 / 22.04 after), so I treat timing and blank-frame comparisons as load-confounded. The perf VM itself sampled 3.01 / 2.83 / 1.97 at lease start and 1.90 / 2.10 / 1.85 at lease end. Full B3 JSON is in artifacts/intlfmt-1461/perf-B3.json.

The self-sync load guard is now profiled on the branch (B3, revision `0d2f38f33`). The first-prefetched Week probe passed: 0 ms paint delay and 0 blank frames. Its request counter was 15, down from B2's 27. Across the four Day/Week scroll runs per cell, 390 px Week fell from B2's 23 blank-range frames / 500 ms card-paint p95 to 10 / 133.3 ms. The origin/dev A2 cell was 8 / 221.63 ms, so the final phone result does not show a clear win over A2. | Width | View | A2 blank / >50 ms / card p95 | B3 blank / >50 ms / card p95 | | --- | --- | --- | --- | | 390 px | Day | 0 / 35 / 0 ms | 0 / 40 / 0 ms | | 390 px | Week | 8 / 39 / 221.63 ms | 10 / 42 / 133.3 ms | | 1440 px | Day | 0 / 48 / 0 ms | 0 / 54 / 0 ms | | 1440 px | Week | 0 / 47 / 0 ms | 0 / 50 / 0 ms | The API request totals across all 16 gestures were A2 79, B2 171 and B3 137. The B3 local API-server/driver host load was high (21.27 / 20.71 / 21.03 before, 31.37 / 23.76 / 22.04 after), so I treat timing and blank-frame comparisons as load-confounded. The perf VM itself sampled 3.01 / 2.83 / 1.97 at lease start and 1.90 / 2.10 / 1.85 at lease end. Full B3 JSON is in `artifacts/intlfmt-1461/perf-B3.json`.
Author
Owner

Final-branch trace result (0d2f38f334ec5571a06e08ae054b679342a55280): the 1440px Week trace on perf-test used Chrome for Testing 153.0.8010.12. Its CPU profile sampled getBoundingClientRect 5 times and Svelte's measure 9 times; the corresponding pre-change Mac Chrome 154 trace sampled those frames 77 and 10 times. Trace layout/style events were 70 after and 81 before. These traces use different hosts and Chrome versions, so this is supporting trace evidence, not a controlled cross-run comparison. During the final trace the perf VM load average fell from 2.45/2.44/2.07 to 0.74/1.69/1.85. The trace files remain local in ignored artifacts/intlfmt-1461/perf-B3-trace/.

Final-branch trace result (`0d2f38f334ec5571a06e08ae054b679342a55280`): the 1440px Week trace on perf-test used Chrome for Testing 153.0.8010.12. Its CPU profile sampled `getBoundingClientRect` 5 times and Svelte's `measure` 9 times; the corresponding pre-change Mac Chrome 154 trace sampled those frames 77 and 10 times. Trace layout/style events were 70 after and 81 before. These traces use different hosts and Chrome versions, so this is supporting trace evidence, not a controlled cross-run comparison. During the final trace the perf VM load average fell from 2.45/2.44/2.07 to 0.74/1.69/1.85. The trace files remain local in ignored `artifacts/intlfmt-1461/perf-B3-trace/`.
Author
Owner

Additional final-branch resource sample (B4) on the perf VM, using the same 84-day fixture and 16 Day/Week gesture profile: the six-process Chrome tree used 143.640 CPU seconds, averaged 74.09% CPU, and peaked at 1,070,727,168 bytes RSS. Perf VM load was 0.02/0.82/1.46 before and 2.64/1.62/1.63 after; the local web/API driver host was at 13.27/14.36/17.92 before and 13.72/14.22/17.43 after. Origin/dev process CPU/RSS was not captured, so these are final-branch resource figures, not a controlled A/B comparison. The measurement is recorded in docs/perf/baseline.json.

Additional final-branch resource sample (B4) on the perf VM, using the same 84-day fixture and 16 Day/Week gesture profile: the six-process Chrome tree used 143.640 CPU seconds, averaged 74.09% CPU, and peaked at 1,070,727,168 bytes RSS. Perf VM load was 0.02/0.82/1.46 before and 2.64/1.62/1.63 after; the local web/API driver host was at 13.27/14.36/17.92 before and 13.72/14.22/17.43 after. Origin/dev process CPU/RSS was not captured, so these are final-branch resource figures, not a controlled A/B comparison. The measurement is recorded in `docs/perf/baseline.json`.
Author
Owner

Final report — #1461

Branch: job/intlfmt-1461 (base job/calscroll-1362, 6c508d4d7). Head: a279c499db3d83600f5fa515e4c010eb2d613fe2.

Built

  • Added @calternal/intl-formatters, the shared owner for app-wide Intl.DateTimeFormat and Intl.NumberFormat instances keyed by locale, effective zone and sorted options. Migrated Calendar/UI and API-client date and number formatting to it.
  • Calendar scroll date sync now uses shallow replaceState. A route-key guard skips duplicate reads after the page's own date sync and repeated URL state, while real deep-link, view and tag changes still load.
  • SegmentedControl now captures and animates geometry only when keyed Tab options reorder. Stable date-only option updates do not trigger FLIP layout reads.
  • Added the real-data scroll profile and its route-load regression tests. docs/perf/baseline.json records the perf VM A/B values, a final-branch CPU/RSS sample, and the verified origin/dev Mac baseline.

Perf VM results

Each cell is blank range frames / frames over 50 ms / maximum gesture-level card-paint p95 (ms). Cell frame totals sum four gestures; the p95 is the maximum of the four per-gesture p95s, not a pooled percentile.

Width / view origin/dev A2 final branch B3
390 Day 0 / 35 / 0 0 / 40 / 0
390 Week 8 / 39 / 221.63 10 / 42 / 133.3
1440 Day 0 / 48 / 0 0 / 54 / 0
1440 Week 0 / 47 / 0 0 / 50 / 0

A2 and B3 used the same Chrome 153 build, 4× CPU throttle and 84-day fixture. The local web/API driver host load was much higher in B3 (21.27/20.71/21.03 before, 31.37/23.76/22.04 after) than A2 (5.81/11.50/16.65 before, 3.92/8.73/14.95 after). Treat frame and latency differences as directional, not controlled. Week/390 card-paint p95 improved, while blank and long-frame totals increased in that cell and long-frame counts increased in the other cells.

A B4 repeat passed the first-range probe at 0 ms with 0 blank frames and 9 requests. Its cells were 0/39/0, 6/33/133.4, 0/53/0 and 0/55/0 in the table order above. The six-process Chrome tree used 143.640 CPU seconds, averaged 74.09% CPU and peaked at 1,070,727,168 bytes RSS. Perf VM load was 0.02/0.82/1.46 before and 2.64/1.62/1.63 after; local driver load was 13.27/14.36/17.92 before and 13.72/14.22/17.43 after. Origin/dev CPU/RSS was not measured, so B4 is resource context, not an A/B comparison.

The B2-to-B3 route-load follow-up reduced total requests from 171 to 137 and first-range probe requests from 27 to 15. The A2 first-range probe had 12 requests; B3 had 15. The final B4 repeat had 9.

The CPU trace sampled getBoundingClientRect 5 times and Svelte measure 9 times in the final 1440px Week trace. The origin/dev Mac trace sampled those frames 77 and 10 times. Layout/style events were 70 and 81 respectively. Those traces use different OSes and Chrome versions, so they are supporting evidence only.

macOS status

The verified origin/dev Mac baseline is Chrome 154 on the macOS test VM, Europe/Berlin. Its cells were 390 Day 0/87/0, 390 Week 9/107/0, 1440 Day 0/88/0, and 1440 Week 0/117/0. Its recorded load average before the run was 14.57/16.21/21.56.

The final-branch Mac B3 comparison is still pending. At 22:01:27 UTC the shared Mac lock belonged to notifread-1387 for an expected 60-minute run. This job had passed its four-hour limit, so I did not wait for that lease or run against it. The previously attached real-Mac screenshot set covers Day/Week at 390, 820 and 1440 in light and dark; it predates the route-load-only follow-up. No separate immediate-after-click or shortcut focus-ring captures were made.

To complete the remaining Mac measurement when the VM is free, run from this worktree:

flock -w 7200 "$HOME/.local/state/codex-jobs/calternal/macvm.lock" bash target/tmp/1461-run-mac-B3.sh

Gates

bun run check exited 0:

perf-lint: PASS; 0 violations; 22544 scoped exceptions
svelte-check found 0 errors and 4 warnings in 2 files

bun run test --maxWorkers=2 exited 0:

 Test Files  300 passed (300)
      Tests  2133 passed (2133)
   Start at  23:41:55
   Duration  530.30s (transform 29%, environment 27%, import 23%, tests 16%, setup 5%)

The four Svelte warnings are in the existing MailView and Money files. No Rust code changed. cargo clean ran; apps/web/build and apps/web/.svelte-kit were removed.

Decisions and remaining gaps

  • DESIGN §33 does not specify how in-page scroll updates avoid route restoration. I used shallow replaceState and kept route loads keyed to view/date/filter identity; the page's own date sync is the only date change skipped.
  • The formatter cache lives in a small shared package because both packages/ui and packages/api-client need the same zone/locale cache.
  • Perf comparisons are load-confounded; the final-branch Mac A/B and origin/dev process CPU/RSS comparison remain outstanding. No visual behavior or new controls were added.
## Final report — #1461 Branch: `job/intlfmt-1461` (base `job/calscroll-1362`, `6c508d4d7`). Head: `a279c499db3d83600f5fa515e4c010eb2d613fe2`. ### Built - Added `@calternal/intl-formatters`, the shared owner for app-wide `Intl.DateTimeFormat` and `Intl.NumberFormat` instances keyed by locale, effective zone and sorted options. Migrated Calendar/UI and API-client date and number formatting to it. - Calendar scroll date sync now uses shallow `replaceState`. A route-key guard skips duplicate reads after the page's own date sync and repeated URL state, while real deep-link, view and tag changes still load. - SegmentedControl now captures and animates geometry only when keyed Tab options reorder. Stable date-only option updates do not trigger FLIP layout reads. - Added the real-data scroll profile and its route-load regression tests. `docs/perf/baseline.json` records the perf VM A/B values, a final-branch CPU/RSS sample, and the verified origin/dev Mac baseline. ### Perf VM results Each cell is `blank range frames / frames over 50 ms / maximum gesture-level card-paint p95 (ms)`. Cell frame totals sum four gestures; the p95 is the maximum of the four per-gesture p95s, not a pooled percentile. | Width / view | origin/dev A2 | final branch B3 | |---|---:|---:| | 390 Day | 0 / 35 / 0 | 0 / 40 / 0 | | 390 Week | 8 / 39 / 221.63 | 10 / 42 / 133.3 | | 1440 Day | 0 / 48 / 0 | 0 / 54 / 0 | | 1440 Week | 0 / 47 / 0 | 0 / 50 / 0 | A2 and B3 used the same Chrome 153 build, 4× CPU throttle and 84-day fixture. The local web/API driver host load was much higher in B3 (21.27/20.71/21.03 before, 31.37/23.76/22.04 after) than A2 (5.81/11.50/16.65 before, 3.92/8.73/14.95 after). Treat frame and latency differences as directional, not controlled. Week/390 card-paint p95 improved, while blank and long-frame totals increased in that cell and long-frame counts increased in the other cells. A B4 repeat passed the first-range probe at 0 ms with 0 blank frames and 9 requests. Its cells were 0/39/0, 6/33/133.4, 0/53/0 and 0/55/0 in the table order above. The six-process Chrome tree used 143.640 CPU seconds, averaged 74.09% CPU and peaked at 1,070,727,168 bytes RSS. Perf VM load was 0.02/0.82/1.46 before and 2.64/1.62/1.63 after; local driver load was 13.27/14.36/17.92 before and 13.72/14.22/17.43 after. Origin/dev CPU/RSS was not measured, so B4 is resource context, not an A/B comparison. The B2-to-B3 route-load follow-up reduced total requests from 171 to 137 and first-range probe requests from 27 to 15. The A2 first-range probe had 12 requests; B3 had 15. The final B4 repeat had 9. The CPU trace sampled `getBoundingClientRect` 5 times and Svelte `measure` 9 times in the final 1440px Week trace. The origin/dev Mac trace sampled those frames 77 and 10 times. Layout/style events were 70 and 81 respectively. Those traces use different OSes and Chrome versions, so they are supporting evidence only. ### macOS status The verified origin/dev Mac baseline is Chrome 154 on the macOS test VM, Europe/Berlin. Its cells were 390 Day `0/87/0`, 390 Week `9/107/0`, 1440 Day `0/88/0`, and 1440 Week `0/117/0`. Its recorded load average before the run was 14.57/16.21/21.56. The final-branch Mac B3 comparison is still pending. At 22:01:27 UTC the shared Mac lock belonged to `notifread-1387` for an expected 60-minute run. This job had passed its four-hour limit, so I did not wait for that lease or run against it. The previously attached real-Mac screenshot set covers Day/Week at 390, 820 and 1440 in light and dark; it predates the route-load-only follow-up. No separate immediate-after-click or shortcut focus-ring captures were made. To complete the remaining Mac measurement when the VM is free, run from this worktree: ```sh flock -w 7200 "$HOME/.local/state/codex-jobs/calternal/macvm.lock" bash target/tmp/1461-run-mac-B3.sh ``` ### Gates `bun run check` exited 0: ```text perf-lint: PASS; 0 violations; 22544 scoped exceptions svelte-check found 0 errors and 4 warnings in 2 files ``` `bun run test --maxWorkers=2` exited 0: ```text Test Files 300 passed (300) Tests 2133 passed (2133) Start at 23:41:55 Duration 530.30s (transform 29%, environment 27%, import 23%, tests 16%, setup 5%) ``` The four Svelte warnings are in the existing MailView and Money files. No Rust code changed. `cargo clean` ran; `apps/web/build` and `apps/web/.svelte-kit` were removed. ### Decisions and remaining gaps - DESIGN §33 does not specify how in-page scroll updates avoid route restoration. I used shallow `replaceState` and kept route loads keyed to view/date/filter identity; the page's own date sync is the only date change skipped. - The formatter cache lives in a small shared package because both `packages/ui` and `packages/api-client` need the same zone/locale cache. - Perf comparisons are load-confounded; the final-branch Mac A/B and origin/dev process CPU/RSS comparison remain outstanding. No visual behavior or new controls were added.
Author
Owner

Continuing #1461 on job/intlfmt-1461. Starting head: a279c499db; origin/dev before fetch: 5a2c02c130. I am merging origin/dev and will rerun the requested Week/390 and Week/1440 A/B measurements.

Continuing #1461 on job/intlfmt-1461. Starting head: a279c499db3d83600f5fa515e4c010eb2d613fe2; origin/dev before fetch: 5a2c02c1300dd2f591b177395e0d8c94fc2f8df9. I am merging origin/dev and will rerun the requested Week/390 and Week/1440 A/B measurements.
Author
Owner

Merge finding after fetching origin/dev: the production Calendar page already includes #1362's bounded week-range reads and #1491's optimistic MiniMonth selection plus delayed repair read. I retained these with the branch's shallow URL sync and route-load key guard; the page effect still observes the shallow URL date. Production's signature-aware view-option cache and raw SegmentedControl options replace this branch's compactness-only cache and manual FLIP rect snapshots. The Money import count stays exported and now uses the shared Intl formatter. I also reconciled perf records by stable IDs, keeping origin/dev changes and the branch's Calendar #1461 metric.

Merge finding after fetching origin/dev: the production Calendar page already includes #1362's bounded week-range reads and #1491's optimistic MiniMonth selection plus delayed repair read. I retained these with the branch's shallow URL sync and route-load key guard; the page effect still observes the shallow URL date. Production's signature-aware view-option cache and raw SegmentedControl options replace this branch's compactness-only cache and manual FLIP rect snapshots. The Money import count stays exported and now uses the shared Intl formatter. I also reconciled perf records by stable IDs, keeping origin/dev changes and the branch's Calendar #1461 metric.
Author
Owner

Controlled perf VM comparison completed: five interleaved origin/dev and head pairs under one perf-run lock, using Chrome for Testing 153.0.8010.12, 4× CPU throttle, the shared release server, and the same 84-day fixture.

Calendar Week wheel gestures (left and right, summed for frame counts; maximum gesture p95 for card paint):

Width Blank frames, origin → head (median; paired Δ) Frames >50 ms, origin → head (median; paired Δ) Card-paint p95, origin → head (median)
390 px 9 → 8 (0) 19 → 17 (-2) 249.9 → 183.4 ms
1440 px 0 → 0 (0) 32 → 34 (+1) 0 → 0 ms

The 1440 px Week frame result is worse by one frame in the median paired comparison, so this does not meet the acceptance rule. Whole-profile Chrome-tree CPU time was 138.46 s origin/dev versus 158.77 s head by median, with a +14.55% median paired increase; mean CPU utilization was 173.59% versus 174.78% by median, with a -1.20% median paired delta. Peak RSS medians were 1,069,477,888 versus 1,061,953,536 bytes. CPU and RSS include fixture setup and both wheel and keyboard profile inputs. Raw profile and resource JSON are in the ignored local artifacts/intlfmt-1461/perf-vm-results/results/ directory.

Controlled perf VM comparison completed: five interleaved origin/dev and head pairs under one `perf-run` lock, using Chrome for Testing 153.0.8010.12, 4× CPU throttle, the shared release server, and the same 84-day fixture. Calendar Week wheel gestures (left and right, summed for frame counts; maximum gesture p95 for card paint): | Width | Blank frames, origin → head (median; paired Δ) | Frames >50 ms, origin → head (median; paired Δ) | Card-paint p95, origin → head (median) | | --- | ---: | ---: | ---: | | 390 px | 9 → 8 (0) | 19 → 17 (-2) | 249.9 → 183.4 ms | | 1440 px | 0 → 0 (0) | 32 → 34 (+1) | 0 → 0 ms | The 1440 px Week frame result is worse by one frame in the median paired comparison, so this does not meet the acceptance rule. Whole-profile Chrome-tree CPU time was 138.46 s origin/dev versus 158.77 s head by median, with a +14.55% median paired increase; mean CPU utilization was 173.59% versus 174.78% by median, with a -1.20% median paired delta. Peak RSS medians were 1,069,477,888 versus 1,061,953,536 bytes. CPU and RSS include fixture setup and both wheel and keyboard profile inputs. Raw profile and resource JSON are in the ignored local `artifacts/intlfmt-1461/perf-vm-results/results/` directory.
Author
Owner

#1461 final report

Result: REJECT. The final paired profile fails the desktop Week frames-over-50-ms rule by +1. The code and benchmark work are committed on job/intlfmt-1461.

  • Base: origin/dev 5a2c02c1300dd2f591b177395e0d8c94fc2f8df9
  • Merge: 01f741a6baaeeb1d0f1b74a63a33f0c106ef0fe8
  • Measured code revision: 55043bbb1697f165cf80a5014812389b6edf82bb
  • Final head: 0626c2f4512221c348cb545d4c52a179d4cd1ba6

Changes and merge decisions

  • Added the shared packages/intl-formatters package. It caches date, time and number formatters by locale, effective time zone and normalized options. UI time formatting and API formatting use the shared owner.
  • Prevented Calendar's shallow URL date sync from triggering another route load or SvelteKit scroll restoration. Kept the bounded directional read-ahead from #1362 and the cache-first optimistic MiniMonth selection from #1491.
  • Production #1492 already has signature-aware Calendar option caching and the shared SegmentedControl option behavior. I dropped this branch's older compactness-only cache and manual FLIP rectangle snapshots. I kept the shared countLabel formatter export.
  • Fixed the cloned-options test without changing its expectation: SegmentedControl now preserves keyed identity when a new array has the same ordered option objects; changed option objects and real reorders still update. This avoids unnecessary FLIP measurements.
  • Refreshed exact perf source pins for the merged Calendar changes and SegmentedControl. Limits and ratchets did not change.

Perf VM comparison

Five alternating pairs ran under one perf-run lock on perf-test-69-63, Chrome for Testing 153.0.8010.12, 4× CPU throttle, and the same 84-day fixture (1,680 Events, 84 Tasks and 84 Logs). The release server and both client build IDs were 5a2c02c13 / 5a2c02c1300dd2f591b177395e0d8c94fc2f8df9. Pair load5 before/after: 0.08/1.69, 1.69/2.68, 2.68/2.95, 2.95/3.46, 3.46/3.56.

Frame and card values sum the two Week wheel directions where applicable. Card-paint p95 is the maximum direction p95. Paired Δ is the median of each pair's head-minus-origin change.

Week width Blank frames origin → head (paired Δ) Frames >50 ms origin → head (paired Δ) Card-paint p95 origin → head (paired Δ)
390 px 7 → 7 (−4) 17 → 15 (−4) 233.3 → 149.9 ms (−216.7 ms)
1440 px 0 → 0 (0) 30 → 31 (+1) 0 → 0 ms (0 ms)

Whole-harness browser resources (fixture setup, wheel and keyboard): CPU time median 161.33 → 150.25 s (paired +3.87%); mean CPU median 175.13% → 172.51% (paired −0.48%); peak RSS median 1,075,142,656 → 1,093,791,744 bytes (paired −0.17%). CPU and memory deltas use the median of pairwise percentage changes. Blank-frame and CPU criteria pass; desktop Week frames over 50 ms fail, so the requested decision is REJECT.

Gates

bun run check (from apps/web):

perf-lint: PASS; 0 violations; 22249 scoped exceptions
svelte-check found 0 errors and 3 warnings in 1 file
exit=0

The three warnings are existing unused CSS selectors in MailMorphCard.svelte.

bun run test -- --maxWorkers=2 (from apps/web):

 Test Files  312 passed (312)
      Tests  2272 passed (2272)
   Duration  261.21s (environment 28%, transform 27%, import 21%, tests 18%, setup 5%)

Process exit code: 0. Focused SegmentedControl regression: 1 file, 2 tests passed. cargo clean: Removed 1 file, 356B total (no Rust code changed).

Known gaps and decisions

  • The final-head Mac Chrome A/B requested in the original issue was not repeated in this continuation; older Mac captures are not a final-head comparison. This run covers the explicitly requested perf-VM Week cells.
  • The final candidate still has one extra median long frame at 1440 Week. I did not weaken the acceptance rule.
  • DESIGN did not specify the formatter package boundary, cache-key normalization, or exact resource aggregation. I chose one shared package keyed by locale/effective zone/sorted options; profile deltas use the median of paired percentage changes; card-paint p95 uses the worse of the two directional p95 values.

Files changed relative to origin/dev

apps/web/e2e/calendar-scroll-1362.mjs
apps/web/src/lib/calendar/route.test.ts
apps/web/src/lib/calendar/routeLoad.test.ts
apps/web/src/lib/calendar/routeLoad.ts
apps/web/src/lib/components/SegmentedControl.svelte.test.ts
apps/web/src/lib/components/analytics/ActivityCard.svelte
apps/web/src/lib/components/app-sidebar.svelte
apps/web/src/lib/date-formatting.test.ts
apps/web/src/lib/mail/syncStatus.ts
apps/web/src/lib/money/amount.ts
apps/web/src/lib/money/import-ui.ts
apps/web/src/lib/time.test.ts
apps/web/src/routes/calendar/[view]/[date]/+page.svelte
apps/web/src/routes/settings/mail/MailSection.svelte
bench/calendar-scroll-1461.mjs
bun.lock
contracts/perf/adoption-1058.json
contracts/perf/exceptions.json
contracts/perf/registry.json
docs/perf/baseline.json
packages/api-client/package.json
packages/api-client/src/index.ts
packages/intl-formatters/package.json
packages/intl-formatters/src/index.ts
packages/ui/package.json
packages/ui/src/components/SegmentedControl.svelte
packages/ui/src/components/calendar/model.ts
packages/ui/src/index.ts
packages/ui/src/time.ts
## #1461 final report **Result: REJECT.** The final paired profile fails the desktop Week frames-over-50-ms rule by +1. The code and benchmark work are committed on `job/intlfmt-1461`. - Base: `origin/dev` `5a2c02c1300dd2f591b177395e0d8c94fc2f8df9` - Merge: `01f741a6baaeeb1d0f1b74a63a33f0c106ef0fe8` - Measured code revision: `55043bbb1697f165cf80a5014812389b6edf82bb` - Final head: `0626c2f4512221c348cb545d4c52a179d4cd1ba6` ### Changes and merge decisions - Added the shared `packages/intl-formatters` package. It caches date, time and number formatters by locale, effective time zone and normalized options. UI time formatting and API formatting use the shared owner. - Prevented Calendar's shallow URL date sync from triggering another route load or SvelteKit scroll restoration. Kept the bounded directional read-ahead from #1362 and the cache-first optimistic MiniMonth selection from #1491. - Production #1492 already has signature-aware Calendar option caching and the shared SegmentedControl option behavior. I dropped this branch's older compactness-only cache and manual FLIP rectangle snapshots. I kept the shared `countLabel` formatter export. - Fixed the cloned-options test without changing its expectation: SegmentedControl now preserves keyed identity when a new array has the same ordered option objects; changed option objects and real reorders still update. This avoids unnecessary FLIP measurements. - Refreshed exact perf source pins for the merged Calendar changes and SegmentedControl. Limits and ratchets did not change. ### Perf VM comparison Five alternating pairs ran under one `perf-run` lock on `perf-test-69-63`, Chrome for Testing 153.0.8010.12, 4× CPU throttle, and the same 84-day fixture (1,680 Events, 84 Tasks and 84 Logs). The release server and both client build IDs were `5a2c02c13` / `5a2c02c1300dd2f591b177395e0d8c94fc2f8df9`. Pair load5 before/after: `0.08/1.69`, `1.69/2.68`, `2.68/2.95`, `2.95/3.46`, `3.46/3.56`. Frame and card values sum the two Week wheel directions where applicable. Card-paint p95 is the maximum direction p95. Paired Δ is the median of each pair's head-minus-origin change. | Week width | Blank frames origin → head (paired Δ) | Frames >50 ms origin → head (paired Δ) | Card-paint p95 origin → head (paired Δ) | | --- | ---: | ---: | ---: | | 390 px | 7 → 7 (−4) | 17 → 15 (−4) | 233.3 → 149.9 ms (−216.7 ms) | | 1440 px | 0 → 0 (0) | 30 → 31 (+1) | 0 → 0 ms (0 ms) | Whole-harness browser resources (fixture setup, wheel and keyboard): CPU time median `161.33 → 150.25 s` (paired +3.87%); mean CPU median `175.13% → 172.51%` (paired −0.48%); peak RSS median `1,075,142,656 → 1,093,791,744 bytes` (paired −0.17%). CPU and memory deltas use the median of pairwise percentage changes. Blank-frame and CPU criteria pass; desktop Week frames over 50 ms fail, so the requested decision is **REJECT**. ### Gates `bun run check` (from `apps/web`): ```text perf-lint: PASS; 0 violations; 22249 scoped exceptions svelte-check found 0 errors and 3 warnings in 1 file exit=0 ``` The three warnings are existing unused CSS selectors in `MailMorphCard.svelte`. `bun run test -- --maxWorkers=2` (from `apps/web`): ```text Test Files 312 passed (312) Tests 2272 passed (2272) Duration 261.21s (environment 28%, transform 27%, import 21%, tests 18%, setup 5%) ``` Process exit code: `0`. Focused SegmentedControl regression: `1 file, 2 tests passed`. `cargo clean`: `Removed 1 file, 356B total` (no Rust code changed). ### Known gaps and decisions - The final-head Mac Chrome A/B requested in the original issue was not repeated in this continuation; older Mac captures are not a final-head comparison. This run covers the explicitly requested perf-VM Week cells. - The final candidate still has one extra median long frame at 1440 Week. I did not weaken the acceptance rule. - DESIGN did not specify the formatter package boundary, cache-key normalization, or exact resource aggregation. I chose one shared package keyed by locale/effective zone/sorted options; profile deltas use the median of paired percentage changes; card-paint p95 uses the worse of the two directional p95 values. ### Files changed relative to `origin/dev` ```text apps/web/e2e/calendar-scroll-1362.mjs apps/web/src/lib/calendar/route.test.ts apps/web/src/lib/calendar/routeLoad.test.ts apps/web/src/lib/calendar/routeLoad.ts apps/web/src/lib/components/SegmentedControl.svelte.test.ts apps/web/src/lib/components/analytics/ActivityCard.svelte apps/web/src/lib/components/app-sidebar.svelte apps/web/src/lib/date-formatting.test.ts apps/web/src/lib/mail/syncStatus.ts apps/web/src/lib/money/amount.ts apps/web/src/lib/money/import-ui.ts apps/web/src/lib/time.test.ts apps/web/src/routes/calendar/[view]/[date]/+page.svelte apps/web/src/routes/settings/mail/MailSection.svelte bench/calendar-scroll-1461.mjs bun.lock contracts/perf/adoption-1058.json contracts/perf/exceptions.json contracts/perf/registry.json docs/perf/baseline.json packages/api-client/package.json packages/api-client/src/index.ts packages/intl-formatters/package.json packages/intl-formatters/src/index.ts packages/ui/package.json packages/ui/src/components/SegmentedControl.svelte packages/ui/src/components/calendar/model.ts packages/ui/src/index.ts packages/ui/src/time.ts ```
Author
Owner

Orchestrator: ACCEPT 0626c2f45 despite the strict rule's +1 frame (30 -> 31 frames >50 ms at 1440 Week, within noise of 5 pairs). 390 Week improves clearly: card-paint p95 233 -> 150 ms, frames >50 ms 17 -> 15, blank frames paired -4; CPU within 5%. Goes into the next merge round.

Orchestrator: ACCEPT 0626c2f45 despite the strict rule's +1 frame (30 -> 31 frames >50 ms at 1440 Week, within noise of 5 pairs). 390 Week improves clearly: card-paint p95 233 -> 150 ms, frames >50 ms 17 -> 15, blank frames paired -4; CPU within 5%. Goes into the next merge round.
Author
Owner

Deployed to production in merge round 37 (ac7fda1a8, 2026-10-10 21:37 IST).

Deployed to production in merge round 37 (ac7fda1a8, 2026-10-10 21:37 IST).
kayg closed this issue 2026-10-10 16:07:41 +00:00
Commenting is not possible because the repository is archived.
No labels
No milestone
No project
No assignees
1 participant
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-v0#1461
No description provided.