perf(web): first-paint credits for the port stacks #1022

Closed
kayg wants to merge 3 commits from perf/first-paint-credits into dev
Owner

First paint is the gate every port PR is measured against, and the ports each add a few hundred bytes of stubs (#902, #904, the rows, tables, attachments, Sharing). This PR moves code the first screen does not need to draw behind lazy imports, one piece per commit, so the ports have room. No behaviour or visual change.

piece first-screen JS (brotli)
the link search (what @ and [[ offer) and its ranking load when the editor is idle -792 B
the copy confirmation's animation is its own chunk -446 B
what following a note link does loads when the editor is idle (a web address still opens inside the click) -269 B
total (227125 B -> 225603 B plain; 226798 B -> 225197 B hash-normalised; CSS unchanged) -1522 B

Each moved piece is fetched when the browser is idle after the editor shows, so the first use finds it already in; nothing waits on the network that did not before.

What I looked at and left alone, and why (sourcemap of the index chunk by module): wipe.ts (6 KB raw) is the account-safety code and an offline sign-out must not depend on a chunk fetch; the icon table is almost all referenced by first-screen modules; daily/log.ts is needed by the first screen's day headings; the Toasts stack is rendered "immediately" on purpose; the CodeMirror, Yjs and Lezer libraries are 372 KB of the 797 KB raw and are the editor itself.

Evidence follows as comments: the bundle gate, 2x before/after screenshots at 390 and 1440, and the perf ABAB against a dev-vs-dev control.

🤖 Generated with Claude Code

First paint is the gate every port PR is measured against, and the ports each add a few hundred bytes of stubs (#902, #904, the rows, tables, attachments, Sharing). This PR moves code the first screen does not need to draw behind lazy imports, one piece per commit, so the ports have room. No behaviour or visual change. | piece | first-screen JS (brotli) | |---|---| | the link search (what `@` and `[[` offer) and its ranking load when the editor is idle | -792 B | | the copy confirmation's animation is its own chunk | -446 B | | what following a note link does loads when the editor is idle (a web address still opens inside the click) | -269 B | | **total** (227125 B -> 225603 B plain; 226798 B -> 225197 B hash-normalised; CSS unchanged) | **-1522 B** | Each moved piece is fetched when the browser is idle after the editor shows, so the first use finds it already in; nothing waits on the network that did not before. What I looked at and left alone, and why (sourcemap of the index chunk by module): `wipe.ts` (6 KB raw) is the account-safety code and an offline sign-out must not depend on a chunk fetch; the icon table is almost all referenced by first-screen modules; `daily/log.ts` is needed by the first screen's day headings; the Toasts stack is rendered "immediately" on purpose; the CodeMirror, Yjs and Lezer libraries are 372 KB of the 797 KB raw and are the editor itself. Evidence follows as comments: the bundle gate, 2x before/after screenshots at 390 and 1440, and the perf ABAB against a dev-vs-dev control. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
The first screen holds a small facade (lib/link-targets-lazy.ts); lib/link-targets.ts and the ranking load once the browser is idle after the editor shows, long before a trigger can be typed, and a search made sooner waits for them. A [[Title]] typed by hand before they are in links to a sibling file, as it does for a note that has no match.

Saving: first-screen JS -792 B brotli (227125 -> 226333 plain), -684 B hash-normalised; CSS unchanged.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
packages/ui/src/lib/copied.ts is a door now (the same confirmCopied); the animation moved to copied-play.ts. A copy made before the chunk is in plays when it arrives (the cached file, a microtask after the first idle). Nothing else changes: same overlay, same timing once it runs.

Saving: first-screen JS -446 B brotli (226333 -> 225887 plain), -480 B hash-normalised; CSS unchanged.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
perf(web): what following a note link does (open, make, card) loads when the browser is idle
Some checks failed
CI / server (pull_request) Has been cancelled
CI / rust (pull_request) Has been cancelled
CI / web (pull_request) Has been cancelled
Markdown extraction contract / markdown-native-contract (pull_request) Has been cancelled
Markdown extraction contract / markdown-editor-contract (pull_request) Has been cancelled
cf974c58be
A web address still opens inside the click (a popup blocker would stop it after a fetch); a link to a note, a day or a missing note waits for lib/links/follow.ts, which the editor fetches when idle, so the first click finds it. Creating a note from the card loads it the same way.

Saving: first-screen JS -269 B brotli (225887 -> 225618 plain), -369 B hash-normalised; CSS unchanged.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Author
Owner

Evidence (issue #1009), head 0253819b7ad87f71e6295fa5eaa9be36008a3e69

gate result
first-screen JS, plain build 225603 B vs dev 227125 B: -1522 B (hash-normalised 225197 B vs 226798 B: -1601 B); CSS 18126 B unchanged
bundle gate the five new lazy chunks needed budget lines (copied-play 0.87, follow 0.90, link-targets 1.08, relink 0.25, search 0.32 KiB) and idle-screens +0.18 KiB: added in the last commit; the gate is being run again on it
specs, Chromium 1440 + 390 links, links-parity, links-look, missing-links, link-suggest, settings-links, swipe-rows, select-rows, slash-menu, tag-picker, typing-latency: 152 passed, 24 skipped
specs, WebKit 1440 + 390 149 passed, 1 failed (missing-links:245 at 390: click on a link did not navigate; 1 in 8 runs; being compared with dev, see below), 26 skipped
perf ABAB x5 + dev-vs-dev control queued behind other lanes (lane-queue-ctl7)

No visual change. The same data served with dev's build and with this build, 2x, light and dark, the list and a note with a link: at 390 the PNGs are byte-identical; at 1440 they differ by 49 to 51 dB PSNR, which is one glyph of the Journal row's time (the day note's time changed between the two runs) and the animated backdrop's noise.

2x before (dev) after (this PR)
list 1440 light
list 1440 dark
list 390 light
list 390 dark
note 1440 light
note 1440 dark
note 390 light
note 390 dark
**Evidence (issue #1009), head `0253819b7ad87f71e6295fa5eaa9be36008a3e69`** | gate | result | |---|---| | first-screen JS, plain build | **225603 B vs dev 227125 B: -1522 B** (hash-normalised 225197 B vs 226798 B: -1601 B); CSS 18126 B unchanged | | bundle gate | the five new lazy chunks needed budget lines (copied-play 0.87, follow 0.90, link-targets 1.08, relink 0.25, search 0.32 KiB) and idle-screens +0.18 KiB: added in the last commit; the gate is being run again on it | | specs, Chromium 1440 + 390 | links, links-parity, links-look, missing-links, link-suggest, settings-links, swipe-rows, select-rows, slash-menu, tag-picker, typing-latency: 152 passed, 24 skipped | | specs, WebKit 1440 + 390 | 149 passed, 1 failed (`missing-links:245` at 390: click on a link did not navigate; 1 in 8 runs; being compared with dev, see below), 26 skipped | | perf ABAB x5 + dev-vs-dev control | queued behind other lanes (`lane-queue-ctl7`) | **No visual change.** The same data served with dev's build and with this build, 2x, light and dark, the list and a note with a link: at 390 the PNGs are byte-identical; at 1440 they differ by 49 to 51 dB PSNR, which is one glyph of the Journal row's time (the day note's time changed between the two runs) and the animated backdrop's noise. | 2x | before (dev) | after (this PR) | |---|---|---| | list 1440 light | ![](https://git.kayg.org/attachments/25050ba5-2fe8-4024-9cee-bb1f9335d478) | ![](https://git.kayg.org/attachments/44b0c3cd-5936-45d7-bbc8-f80aadc29bd6) | | list 1440 dark | ![](https://git.kayg.org/attachments/06fc2dd8-f4fa-465c-a269-c07e1cf5953b) | ![](https://git.kayg.org/attachments/ea174889-ef69-40eb-a43e-5051207ac1cc) | | list 390 light | ![](https://git.kayg.org/attachments/15b8846f-1f7f-488d-a313-0690584900bc) | ![](https://git.kayg.org/attachments/09758663-a0de-4629-8741-4103eb17d661) | | list 390 dark | ![](https://git.kayg.org/attachments/ebfb98a8-6794-45ea-8a82-addc133e67be) | ![](https://git.kayg.org/attachments/50f3bd8d-f989-47f6-95a2-808663b16211) | | note 1440 light | ![](https://git.kayg.org/attachments/0c66e9a3-3c00-42b6-8cf4-8d39c3083510) | ![](https://git.kayg.org/attachments/fa61eef1-fff1-4fd0-a9bc-d587bcb12ecd) | | note 1440 dark | ![](https://git.kayg.org/attachments/f1ca0f36-83bb-4d52-8258-337cf09b52a9) | ![](https://git.kayg.org/attachments/a6130666-2248-46b7-aaec-097e3823fc93) | | note 390 light | ![](https://git.kayg.org/attachments/0c9e5dff-a5d3-4470-aa70-aec3e228efc1) | ![](https://git.kayg.org/attachments/c31d6cb0-1956-480c-b65d-7986af59570f) | | note 390 dark | ![](https://git.kayg.org/attachments/0583c52e-f603-4a7f-bc3e-f45e1829bd61) | ![](https://git.kayg.org/attachments/a06d8330-a244-42a2-a6c2-5e04d6b9baef) |
Author
Owner

Update, head 0253819b7ad87f71e6295fa5eaa9be36008a3e69.

  • Bundle gate: passes on this head (the five new lazy chunks have their budget lines; idle-screens +0.18 KiB).
  • missing-links:245 at WebKit 390: it failed once in 8 runs on dev-02 under load. Run 16 times on dev-01 on both builds, it passes 16 of 16 on this PR and 16 of 16 on dev, so it is a load-dependent flake of the spec, not something this PR changes.
  • Perf ABAB x5 with the dev-vs-dev control is queued with one FIFO ticket (ports) together with the tables, attachments and Contacts runs.

Honest size: -1522 B, short of the 4.5 KB aimed for. The rest of the index chunk is the editor's libraries (CodeMirror, Yjs, Lezer: 372 KB of 797 KB raw) and code the first screen needs; the pieces I looked at and rejected are listed in the description. Larger credits would need behaviour risks I did not take: lazy Yjs and the sync client until a note goes live, splitting the sign-out wipe from its offline path, or deferring the toast stack (its first toast is meant to be immediate).

**Update, head `0253819b7ad87f71e6295fa5eaa9be36008a3e69`.** - **Bundle gate: passes** on this head (the five new lazy chunks have their budget lines; idle-screens +0.18 KiB). - **`missing-links:245` at WebKit 390:** it failed once in 8 runs on dev-02 under load. Run 16 times on dev-01 on both builds, it passes 16 of 16 on this PR and 16 of 16 on dev, so it is a load-dependent flake of the spec, not something this PR changes. - **Perf ABAB x5 with the dev-vs-dev control** is queued with one FIFO ticket (`ports`) together with the tables, attachments and Contacts runs. Honest size: -1522 B, short of the 4.5 KB aimed for. The rest of the index chunk is the editor's libraries (CodeMirror, Yjs, Lezer: 372 KB of 797 KB raw) and code the first screen needs; the pieces I looked at and rejected are listed in the description. Larger credits would need behaviour risks I did not take: lazy Yjs and the sync client until a note goes live, splitting the sign-out wipe from its offline path, or deferring the toast stack (its first toast is meant to be immediate).
Author
Owner

READY FOR MERGE: first-paint credits (head e65ef6510e)

Rebased on dev 1619002ac (#1025). No behaviour change: the link search, the copy confirmation and link following load when the browser is idle instead of in the first screen.

check dev 1619002ac this PR
first paint, brotli (plain) 227189 B 225554 B (−1635 B)
first paint, hash-normalised 226798 B 225197 B (−1601 B)
first-screen CSS 18126 B 18126 B
bundle gate (perf/web.sh --bundle-only --gate) passes at this head
budget total 508.92 KiB (≤ 543.9), sum of the lines; index line −1.54, five new lazy lines at measured +0.03

The saving (−1.6 KB) covers Sharing #842's +1.19 KB once this merges (it counts for the PR that carries it only while dev's baseline has not moved, so Sharing's gate should be re-measured after this lands).

Specs (chromium and webkit, 1440 and 390; preload, lazy-ui, lazy-offline, glass, shortcuts, links, links-parity, missing-links, link-suggest, slash-menu, tag-picker, daily, typing-latency, lazy-styled, picker-lazy, tasks-lazy), this PR vs dev, same binary:

passed failed skipped
dev 282 24 58
this PR 283 23 58

The 23 failures here are all among dev's 24 (same specs, same projects): preload:118 (×4 projects), preload:89 (×6 at 390), glass:76 and lazy-ui:70 at 390, shortcuts:280 at 1440, lazy-offline:3 chromium-390. Dev has one more (missing-links:228 webkit-390, a flake that passed here). Nothing new fails with this PR. Those 23 are dev's own failures, not caused or fixed here.

Screenshots below: list, note and the [[ link search open, light/dark at 1440 and 390, 2x, dev vs this PR on identical seeded data. Pixel difference ≤ 0.02 % of the image in every pair (clock text and anti-aliasing only; compare -metric AE). Perf rides my queued perf ticket.

Screenshots (2x; light and dark; 1440x900 and 390x844). Left: dev (1619002ac). Right: this PR. Same data, same server.

list

dev this PR
1440 light
1440 dark
390 light
390 dark

note

dev this PR
1440 light
1440 dark
390 light
390 dark

search

dev this PR
1440 light
1440 dark
390 light
390 dark
## READY FOR MERGE: first-paint credits (head e65ef6510efee5dc7f03f2f281ae2cd01fc751ed) Rebased on dev `1619002ac` (#1025). No behaviour change: the link search, the copy confirmation and link following load when the browser is idle instead of in the first screen. | check | dev `1619002ac` | this PR | |---|---|---| | first paint, brotli (plain) | 227189 B | 225554 B (−1635 B) | | first paint, hash-normalised | 226798 B | 225197 B (−1601 B) | | first-screen CSS | 18126 B | 18126 B | | bundle gate (`perf/web.sh --bundle-only --gate`) | | passes at this head | | budget total | | 508.92 KiB (≤ 543.9), sum of the lines; index line −1.54, five new lazy lines at measured +0.03 | The saving (−1.6 KB) covers Sharing #842's +1.19 KB once this merges (it counts for the PR that carries it only while dev's baseline has not moved, so Sharing's gate should be re-measured after this lands). **Specs** (chromium and webkit, 1440 and 390; preload, lazy-ui, lazy-offline, glass, shortcuts, links, links-parity, missing-links, link-suggest, slash-menu, tag-picker, daily, typing-latency, lazy-styled, picker-lazy, tasks-lazy), this PR vs dev, same binary: | | passed | failed | skipped | |---|---|---|---| | dev | 282 | 24 | 58 | | this PR | 283 | 23 | 58 | The 23 failures here are all among dev's 24 (same specs, same projects): preload:118 (×4 projects), preload:89 (×6 at 390), glass:76 and lazy-ui:70 at 390, shortcuts:280 at 1440, lazy-offline:3 chromium-390. Dev has one more (missing-links:228 webkit-390, a flake that passed here). Nothing new fails with this PR. Those 23 are dev's own failures, not caused or fixed here. **Screenshots** below: list, note and the `[[` link search open, light/dark at 1440 and 390, 2x, dev vs this PR on identical seeded data. Pixel difference ≤ 0.02 % of the image in every pair (clock text and anti-aliasing only; `compare -metric AE`). Perf rides my queued perf ticket. ### Screenshots (2x; light and dark; 1440x900 and 390x844). Left: dev (1619002ac). Right: this PR. Same data, same server. **list** | | dev | this PR | |---|---|---| | 1440 light | ![](https://git.kayg.org/attachments/ba1e658a-1b4a-47f5-8030-9b6540986436) | ![](https://git.kayg.org/attachments/1c1c42f9-5efe-42d5-974f-9e1733ff9ab8) | | 1440 dark | ![](https://git.kayg.org/attachments/e79446ba-175a-4e86-913d-3c04c670d488) | ![](https://git.kayg.org/attachments/540d8e71-a07c-4b21-bd85-a701851f72d7) | | 390 light | ![](https://git.kayg.org/attachments/4ef7f19a-4238-4b1a-aeb3-3ba04f025ef1) | ![](https://git.kayg.org/attachments/f84e4c54-fa46-444c-8452-dcd982822e4b) | | 390 dark | ![](https://git.kayg.org/attachments/15e9d83c-0c6c-4815-aefc-d896cb3bab4d) | ![](https://git.kayg.org/attachments/c523d77f-6a5d-471b-aa97-314593348928) | **note** | | dev | this PR | |---|---|---| | 1440 light | ![](https://git.kayg.org/attachments/07fd8d37-20b4-410a-a57e-12ecdd532302) | ![](https://git.kayg.org/attachments/86927812-d56a-49ce-b7c5-dfb4ad05c44a) | | 1440 dark | ![](https://git.kayg.org/attachments/fa916307-1df5-480d-948d-ee652628fe76) | ![](https://git.kayg.org/attachments/fb192b9d-efbf-4312-88d6-b44dd462aac5) | | 390 light | ![](https://git.kayg.org/attachments/87736621-d82b-488b-bf9e-6e77546ab326) | ![](https://git.kayg.org/attachments/29d47ee3-63d5-4937-80a5-227b7686af58) | | 390 dark | ![](https://git.kayg.org/attachments/02a931ef-8aa9-401a-971f-b1ea77aa2259) | ![](https://git.kayg.org/attachments/1b39b832-644e-4111-aacf-6b4d62a7d22b) | **search** | | dev | this PR | |---|---|---| | 1440 light | ![](https://git.kayg.org/attachments/bd9f77ee-fbb5-4972-abda-22c90bcfef04) | ![](https://git.kayg.org/attachments/7c09a9db-45b8-4a34-b48e-c06b964ea539) | | 1440 dark | ![](https://git.kayg.org/attachments/6caa0735-be5f-42a7-88c0-5b6f5903d02e) | ![](https://git.kayg.org/attachments/d5c1adc8-144b-4c45-b859-0597adee1f67) | | 390 light | ![](https://git.kayg.org/attachments/b8f44fa0-0bcd-461d-91c1-6eea29cc0ac6) | ![](https://git.kayg.org/attachments/086cb70d-f2e2-4d45-8b72-f2e9ae3792df) | | 390 dark | ![](https://git.kayg.org/attachments/70400050-3a1b-47b8-9444-a544d448e323) | ![](https://git.kayg.org/attachments/e87175ee-22a7-49aa-aaf3-069f7edf61c7) |
Author
Owner

READY FOR MERGE: first-paint credits, rebased on dev 3f079de39 (head 17010f469)

Rebased onto current dev (#909, #1025, #1029 in). The budgets conflict is gone: the lines are regenerated from a fresh build of this head on top of dev's own file.

A fix since the last READY: after #1029 the preload spec palette … intent prepares only its own screen before idle (preload:118) failed here (and passed on dev). Cause: the link search made lib/search.ts a module shared by the Palette and the idle-loaded link search, so the bundler gave it a chunk of its own and the Palette's Control-key preload fetched two files. It now travels in the dates chunk (the same trick #1029 used for the date words), with one commit: perf(web): the note ranking (lib/search) travels in the dates chunk….

check dev 3f079de39 this PR
first paint, brotli (plain) 227240 B 225403 B (−1837 B)
first paint, hash-normalised 226769 B 225140 B (−1629 B)
first-screen CSS 18126 B 18126 B
bundle gate (perf/web.sh --bundle-only --gate) passes at this head
budget total 506.34 KiB 508.04 KiB (≤ 543.9): index line 222.01 → 220.33, dates 1.48 → 1.74, four new lazy lines (copied-play 0.87, follow 0.91, link-targets 1.09, relink 0.25); total = sum of the lines

Specs, chromium and webkit at 1440 and 390: preload, lazy-ui, lazy-offline, link-suggest, links, shortcuts, slash-menu. 145 passed, 9 failed, 46 skipped. Dev on the same specs (without slash-menu): 118 passed, 8 failed, 42 skipped. The 9 here are dev's 8 (lazy-ui:70 at 390 ×2 projects, preload:89 ×3 at 390 ×2 projects) plus lazy-offline:3 at chromium-390, which is a flake on dev too (reruns: credits pass/fail, dev fail/fail). preload:118 passes in all four projects. Nothing new fails with this PR.

The 2× light/dark shots from the previous comment (list, note, [[ search; ≤ 0.02 % pixel difference vs dev) still apply: the only change since is a bundler grouping rule, no code or CSS. Perf rides my queued ticket.

## READY FOR MERGE: first-paint credits, rebased on dev `3f079de39` (head 17010f469) Rebased onto current dev (#909, #1025, #1029 in). The budgets conflict is gone: the lines are regenerated from a fresh build of this head on top of dev's own file. **A fix since the last READY:** after #1029 the preload spec `palette … intent prepares only its own screen before idle` (preload:118) failed here (and passed on dev). Cause: the link search made `lib/search.ts` a module shared by the Palette and the idle-loaded link search, so the bundler gave it a chunk of its own and the Palette's Control-key preload fetched two files. It now travels in the `dates` chunk (the same trick #1029 used for the date words), with one commit: `perf(web): the note ranking (lib/search) travels in the dates chunk…`. | check | dev `3f079de39` | this PR | |---|---|---| | first paint, brotli (plain) | 227240 B | 225403 B (−1837 B) | | first paint, hash-normalised | 226769 B | 225140 B (−1629 B) | | first-screen CSS | 18126 B | 18126 B | | bundle gate (`perf/web.sh --bundle-only --gate`) | | passes at this head | | budget total | 506.34 KiB | 508.04 KiB (≤ 543.9): index line 222.01 → 220.33, dates 1.48 → 1.74, four new lazy lines (copied-play 0.87, follow 0.91, link-targets 1.09, relink 0.25); total = sum of the lines | **Specs**, chromium and webkit at 1440 and 390: preload, lazy-ui, lazy-offline, link-suggest, links, shortcuts, slash-menu. 145 passed, 9 failed, 46 skipped. Dev on the same specs (without slash-menu): 118 passed, 8 failed, 42 skipped. The 9 here are dev's 8 (lazy-ui:70 at 390 ×2 projects, preload:89 ×3 at 390 ×2 projects) plus `lazy-offline:3` at chromium-390, which is a flake on dev too (reruns: credits pass/fail, dev fail/fail). `preload:118` passes in all four projects. Nothing new fails with this PR. The 2× light/dark shots from the previous comment (list, note, `[[` search; ≤ 0.02 % pixel difference vs dev) still apply: the only change since is a bundler grouping rule, no code or CSS. Perf rides my queued ticket.
Author
Owner

Perf (perf-02, Chromium 4x slowdown, 10k notes, 5 interleaved rounds, dev built from 3f079de39 run twice as a control; medians of per-run p50 / p95, ms):

metric dev A dev B (control) #1022 credits #849 Contacts #854 tables #861 attachments
blaze.shown p50 / p95 36.2 / 64.7 36.0 / 65.7 35.5 / 67.3 37.3 / 65.1 35.1 / 62.3 34.7 / 66.6
type.long_note p50 / p95 21.9 / 55.5 23.5 / 53.4 22.8 / 55.2 23.3 / 54.8 21.8 / 57.0 26.3 / 61.5
type.nested_list p50 / p95 42.1 / 51.0 42.0 / 51.3 43.0 / 52.5 42.4 / 51.0 42.2 / 50.8 43.2 / 52.2
type.code_block p50 / p95 23.9 / 34.8 24.0 / 47.3 24.4 / 52.9 28.0 / 47.5 24.9 / 53.6 25.7 / 53.1
type.code_note_prose p50 / p95 28.0 / 63.0 29.6 / 64.0 29.6 / 68.6 33.4 / 68.5 27.9 / 69.5 37.1 / 71.2
blaze.cpu 76.8 76.3 75.8 75.8 75.4 77.2
blaze.long_task_max 157 153 157 151 149 162

The dev-vs-dev control moves by as much as any arm (code_block p95 34.8 vs 47.3; long_note p95 53.4 vs 55.5), so there is no change beyond the noise on any metric, for any arm. Arms are the heads built from the rebased branches (#854 f58c71010, #861 f20b9457b, #849 as 144013926 before its budget-only commit, #1022 17010f469).

**Perf** (perf-02, Chromium 4x slowdown, 10k notes, 5 interleaved rounds, dev built from `3f079de39` run twice as a control; medians of per-run p50 / p95, ms): | metric | dev A | dev B (control) | #1022 credits | #849 Contacts | #854 tables | #861 attachments | |---|---|---|---|---|---|---| | blaze.shown p50 / p95 | 36.2 / 64.7 | 36.0 / 65.7 | 35.5 / 67.3 | 37.3 / 65.1 | 35.1 / 62.3 | 34.7 / 66.6 | | type.long_note p50 / p95 | 21.9 / 55.5 | 23.5 / 53.4 | 22.8 / 55.2 | 23.3 / 54.8 | 21.8 / 57.0 | 26.3 / 61.5 | | type.nested_list p50 / p95 | 42.1 / 51.0 | 42.0 / 51.3 | 43.0 / 52.5 | 42.4 / 51.0 | 42.2 / 50.8 | 43.2 / 52.2 | | type.code_block p50 / p95 | 23.9 / 34.8 | 24.0 / 47.3 | 24.4 / 52.9 | 28.0 / 47.5 | 24.9 / 53.6 | 25.7 / 53.1 | | type.code_note_prose p50 / p95 | 28.0 / 63.0 | 29.6 / 64.0 | 29.6 / 68.6 | 33.4 / 68.5 | 27.9 / 69.5 | 37.1 / 71.2 | | blaze.cpu | 76.8 | 76.3 | 75.8 | 75.8 | 75.4 | 77.2 | | blaze.long_task_max | 157 | 153 | 157 | 151 | 149 | 162 | The dev-vs-dev control moves by as much as any arm (code_block p95 34.8 vs 47.3; long_note p95 53.4 vs 55.5), so there is no change beyond the noise on any metric, for any arm. Arms are the heads built from the rebased branches (#854 `f58c71010`, #861 `f20b9457b`, #849 as `144013926` before its budget-only commit, #1022 `17010f469`).
Author
Owner

READY FOR MERGE: first-paint credits, rebased on dev d0bf2838c (head 81f692826)

Conflicts resolved: vite.config.ts keeps #1036's sheet-kit group (before idle-screens, unchanged) and dev's page-dim in the dates group, and adds lib/search to it. perf/budgets.json is regenerated from a fresh build of this head on top of dev's file.

check dev d0bf2838c this PR
first paint, plain brotli 228311 B 226694 B (−1617 B)
first paint, hash-normalised 227962 B 226365 B (−1597 B)
first-screen CSS 18234 B 18234 B
bundle gate passes at this head
budget total 513.50 KiB 515.25 KiB (≤ 543.9): index 223.20 → 221.59, idle-screens +0.07, dates 1.63 → 1.81, new lines copied-play 0.87, follow 0.90, link-targets 1.09, relink 0.25

Specs (preload, lazy-ui, lazy-offline; chromium and webkit at 1440 and 390): 74 passed, 10 skipped, 0 failed. lazy-offline:3 is green, and so are lazy-ui:70, preload:89 and preload:118 in all four projects. The earlier shots (list, note, [[ search, ≤ 0.02 % pixel difference vs dev) still apply: since then only a bundler grouping rule and budget lines changed.

## READY FOR MERGE: first-paint credits, rebased on dev `d0bf2838c` (head `81f692826`) Conflicts resolved: `vite.config.ts` keeps #1036's `sheet-kit` group (before idle-screens, unchanged) and dev's `page-dim` in the `dates` group, and adds `lib/search` to it. `perf/budgets.json` is regenerated from a fresh build of this head on top of dev's file. | check | dev `d0bf2838c` | this PR | |---|---|---| | first paint, plain brotli | 228311 B | 226694 B (−1617 B) | | first paint, hash-normalised | 227962 B | 226365 B (−1597 B) | | first-screen CSS | 18234 B | 18234 B | | bundle gate | | passes at this head | | budget total | 513.50 KiB | 515.25 KiB (≤ 543.9): index 223.20 → 221.59, idle-screens +0.07, dates 1.63 → 1.81, new lines copied-play 0.87, follow 0.90, link-targets 1.09, relink 0.25 | **Specs** (preload, lazy-ui, lazy-offline; chromium and webkit at 1440 and 390): 74 passed, 10 skipped, **0 failed**. `lazy-offline:3` is green, and so are `lazy-ui:70`, `preload:89` and `preload:118` in all four projects. The earlier shots (list, note, `[[` search, ≤ 0.02 % pixel difference vs dev) still apply: since then only a bundler grouping rule and budget lines changed.
Author
Owner

READY FOR MERGE, again: first-paint credits, head db34f2268 (on dev 0878cb550, #876)

Dev moved to #876 while the last READY was open and perf/budgets.json conflicted again, so this is rebased on 0878cb550 with the budgets regenerated from a fresh build. It also merges cleanly with 7b03bfcea (#1039; git merge-tree, no conflicts). vite.config.ts still keeps #1036's sheet-kit group and page-dim in dates, plus lib/search.

check dev 0878cb550 this PR
first paint, plain brotli 229021 B 227848 B (−1173 B)
first paint, hash-normalised 228521 B 227107 B (−1414 B)
first-screen CSS 18234 B 18234 B
bundle gate passes at this head
budget total 523.03 KiB 525.01 KiB (≤ 543.9): index 224.00 → 222.71, dates 1.63 → 1.80, new lines copied-play 0.87, follow 0.90, link-targets 1.08, relink 0.25; other lines kept at dev's values

Specs (preload, lazy-ui, lazy-offline; chromium and webkit at 1440 and 390): 74 passed, 10 skipped, 0 failed. The saving is a little smaller than before (−1.6 KB on d0bf2838c) because #876 grew the first screen around the same modules.

If another merge lands first, the only conflict to expect is perf/budgets.json: take dev's file and keep the changes in my budget commit (index, dates, four new lines, total).

## READY FOR MERGE, again: first-paint credits, head `db34f2268` (on dev `0878cb550`, #876) Dev moved to #876 while the last READY was open and `perf/budgets.json` conflicted again, so this is rebased on `0878cb550` with the budgets regenerated from a fresh build. It also merges cleanly with `7b03bfcea` (#1039; `git merge-tree`, no conflicts). `vite.config.ts` still keeps #1036's `sheet-kit` group and page-dim in `dates`, plus `lib/search`. | check | dev `0878cb550` | this PR | |---|---|---| | first paint, plain brotli | 229021 B | 227848 B (−1173 B) | | first paint, hash-normalised | 228521 B | 227107 B (−1414 B) | | first-screen CSS | 18234 B | 18234 B | | bundle gate | | passes at this head | | budget total | 523.03 KiB | 525.01 KiB (≤ 543.9): index 224.00 → 222.71, dates 1.63 → 1.80, new lines copied-play 0.87, follow 0.90, link-targets 1.08, relink 0.25; other lines kept at dev's values | Specs (preload, lazy-ui, lazy-offline; chromium and webkit at 1440 and 390): 74 passed, 10 skipped, 0 failed. The saving is a little smaller than before (−1.6 KB on `d0bf2838c`) because #876 grew the first screen around the same modules. If another merge lands first, the only conflict to expect is `perf/budgets.json`: take dev's file and keep the changes in my budget commit (index, dates, four new lines, total).
Author
Owner

Merged into dev locally (head db34f2268 is in origin/dev); closing.

Merged into dev locally (head `db34f2268` is in origin/dev); closing.
kayg closed this pull request 2026-11-09 18:55:10 +00:00
Some checks failed
CI / server (pull_request) Has been cancelled
CI / rust (pull_request) Has been cancelled
CI / web (pull_request) Has been cancelled
Markdown extraction contract / markdown-native-contract (pull_request) Has been cancelled
Markdown extraction contract / markdown-editor-contract (pull_request) Has been cancelled

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!1022
No description provided.