Fix web speed regressions from full train #518

Closed
kayg wants to merge 0 commits from issue/327-web-fast-3 into dev
Owner

This PR replaces #515 and fixes the web regressions from the full train in issue #327.

Changes:

  • Keep missing-link state requests active while the notes list is filling, and cover the settling-list response with an end-to-end test.
  • Clear pending arrow-key walks when browser history changes, with a deterministic Back test.
  • Make the late-list undo fixture trigger a real journal refresh without deadlocking on a held list read.
  • Wait for fonts and opening animations before measuring the width transition.

Checks:

  • Playwright (--workers=1 --repeat-each=3): chromium-1440 18 passed / 0 skipped; chromium-390 9 passed / 9 skipped; webkit-1440 18 passed / 0 skipped; webkit-390 9 passed / 9 skipped. Overall output: 18 skipped, 54 passed (3.6m).
  • svelte-check found 0 errors and 12 warnings in 7 files
  • Editor unit tests: Test Files 18 passed (18); Tests 135 passed (135).
  • 100k cold boot: web.chromium.boot.cold_tbt ms {"n":1,"p50":425.1,"p95":425.1,"max":425.1}; budget result was ok (p95 ≤ 1000 ms). The same perf report also printed over budget: web.bundle.first_css_brotli@0: p95 22.9 > 22.1; this run does not establish the cause of that bundle measurement.

Base: dev.

This PR replaces #515 and fixes the web regressions from the full train in issue #327. Changes: - Keep missing-link state requests active while the notes list is filling, and cover the settling-list response with an end-to-end test. - Clear pending arrow-key walks when browser history changes, with a deterministic Back test. - Make the late-list undo fixture trigger a real journal refresh without deadlocking on a held list read. - Wait for fonts and opening animations before measuring the width transition. Checks: - Playwright (`--workers=1 --repeat-each=3`): chromium-1440 18 passed / 0 skipped; chromium-390 9 passed / 9 skipped; webkit-1440 18 passed / 0 skipped; webkit-390 9 passed / 9 skipped. Overall output: `18 skipped`, `54 passed (3.6m)`. - `svelte-check found 0 errors and 12 warnings in 7 files` - Editor unit tests: `Test Files 18 passed (18)`; `Tests 135 passed (135)`. - 100k cold boot: `web.chromium.boot.cold_tbt ms {"n":1,"p50":425.1,"p95":425.1,"max":425.1}`; budget result was `ok` (p95 ≤ 1000 ms). The same perf report also printed `over budget: web.bundle.first_css_brotli@0: p95 22.9 > 22.1`; this run does not establish the cause of that bundle measurement. Base: `dev`.
kayg added 15 commits 2026-10-17 02:24:14 +00:00
perf/web.sh measures the built app as production serves it on 10k and 100k
fixture Homes, Chromium (CPU 4x) and WebKit: bundle sizes, boot (TBT as
web.dev defines it, every long task, first paint, time to interactive),
keystroke to paint, the blaze test (#271), scrolling, memory, layout shift
and main-thread CPU. web.* budgets in perf/budgets.json; CI gates the
bundle sizes. docs/perf/web.md.

Replaces #360.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018Yyy8fQGxPLkLa8v8NXz7T
- frontmatterEnd walks lines without copying and remembers per document.
- The note metadata keeps `base` under its own key, written only when it
  changed (older records still read).
- A preview whose text matches the live document swaps its binding in
  place (a compartment) instead of building and parsing a new state.
- Clouds worked out in slices (lib/slices.ts), date labels morph only once
  tapped, the offline merge code loads only when a merge runs.

Replaces #402 and part of #454.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018Yyy8fQGxPLkLa8v8NXz7T
- lib/notes-index.ts: notes newest first by binary search, tag counts,
  file to id, the Journal's order; views are told once per batch.
- groups() slices ordered lists by binary search; NoteList works out its
  visible rows from group sizes (lib/list-window.ts). Nothing walks every
  note on the main thread.
- The background fill (#422, pages of 2000) is fetched and parsed in a
  worker (lib/notes-fill.worker.ts) and handed over 250 notes at a time;
  without a worker, pages of 500 the plain way.
- The first note's text comes over plain HTTP (notes.peek) when nothing is
  remembered, instead of waiting for its room; peeks come 12 at a time.
- Typing: properties re-read only when an edit reaches them, the bar's
  block list replaced only when it held something.
- Theme colour once per frame; the Settings bar builds at the next idle.

Replaces #394, #407 and the rest of #454.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018Yyy8fQGxPLkLa8v8NXz7T
Fill pages are fetched by a worker now, whose requests the page doesn't
always see: the app marks html[data-listed] when the whole list is in, and
the harness waits for it (builds without the fill worker: request silence).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018Yyy8fQGxPLkLa8v8NXz7T
Test stale note lists deterministically
Some checks failed
CI / server (pull_request) Successful in 26s
CI / rust (pull_request) Failing after 2m4s
CI / web (pull_request) Failing after 47s
3c2c2bc040
Fix web speed train regressions
Some checks failed
CI / server (pull_request) Successful in 26s
CI / rust (pull_request) Failing after 1m53s
CI / web (pull_request) Failing after 34s
f20c348e29
Author
Owner

Landed in train v, #525.

Train v ran the full suite per project (11 projects), plus fmt, clippy, workspace tests and the build. fmt, clippy and the workspace tests are all green.

  • Passed: chromium-1440, throttled-390, throttled-1440, flow, passkeys, prefs-chromium, prefs-webkit and contrast.
  • First-run failures, all green on a 3x rerun:
    • missing-links:379 on chromium-390: 54 of 54;
    • tooltips on webkit-390: 9 of 9;
    • tree:176 on webkit-1440: 21 of 21.

Contents:

  • #518: web speed. The 100k cold TBT drops from 22.5 s to about 0.4 s on an idle host, with the stale-list guard kept;
  • #519: delete waits for the history writer, so a link read right after a delete never says New.

Merging.

Landed in train v, #525. Train v ran the full suite per project (11 projects), plus fmt, clippy, workspace tests and the build. fmt, clippy and the workspace tests are all green. - **Passed:** chromium-1440, throttled-390, throttled-1440, flow, passkeys, prefs-chromium, prefs-webkit and contrast. - **First-run failures, all green on a 3x rerun:** - `missing-links:379` on chromium-390: 54 of 54; - `tooltips` on webkit-390: 9 of 9; - `tree:176` on webkit-1440: 21 of 21. Contents: - #518: web speed. The 100k cold TBT drops from 22.5 s to about 0.4 s on an idle host, with the stale-list guard kept; - #519: delete waits for the history writer, so a link read right after a delete never says New. Merging.
kayg closed this pull request 2026-10-17 07:06:41 +00:00
Some checks failed
CI / server (pull_request) Successful in 26s
CI / rust (pull_request) Failing after 1m53s
CI / web (pull_request) Failing after 34s

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